헤더 전용 라이브러리가 더 효율적입니까?


48

가정

  1. C ++ 용 헤더 전용 라이브러리의 장점 중 하나는 별도로 컴파일 할 필요가 없다는 것입니다.

  2. C 및 C ++ inline에서 함수가 헤더 파일 *에 정의 된 경우에만 의미가 있습니다.

  3. 전통적으로 C에서는 .c / .h 레이아웃이 사용되었으며, 여기서 헤더는 번역 단위의 최소 공용 인터페이스를 나타냅니다. 마찬가지로 .cpp / hpp.

질문

헤더 전용 라이브러리는 일반적으로 기존 레이아웃보다 코드 및 실행 시간이 더 효율적입니까? 그렇다면 광범위한 인라인 또는 기타 최적화로 인한 것입니까?

*-헤더에 함수를 정의하면 컴파일러가 모든 번역 단위를 컴파일하는 동안 구현을 볼 수 있으며 실제로 코드 인라인 가능


2
많은 최신 C ++ 링커 (GCC, MSVC, ICC 등)가 개별 번역 단위에서 코드를 인라인 할 수있는 방법에 놀랄 것입니다. 링커를 최적화하는 것이 내 기대를 무시하고 어쨌든 인라인을 관리하는 횟수를 고려할 때 효율성 관점에서 "일반적으로 아니오"라고 말하고 싶습니다 (헤더에 인라인하거나 별도의 정적으로 링크 된 라이브러리에서 구현을 제공 할 수있는 dylib 컨텍스트는 제외됩니다) . 그러나 인터페이스와 구현 모두에서 안정적인 헤더 전용 라이브러리는 새로운 프로젝트에 쉽게 배포 할 수 있기 때문에 섹시 할 수 있습니다.

1
나는 이것이 완전한 답을 얻을 가치가 있다는 것을 모르지만, 헤더 전용 libs의 큰 이점 중 하나는 설치 및 사용법이 쉽다는 것입니다 : Download, #include "lib.h (pp)", done.
WeRelic

답변:


44

C ++ 용 헤더 전용 라이브러리의 장점 중 하나는 별도로 컴파일 할 필요가 없다는 것입니다

아닙니다. 그것은 장점이 아닙니다. 정반대의 경우입니다. 라이브러리의 주요 부분은 포함되는 한 번이 아니라 자주 컴파일되어야합니다. 일반적으로 컴파일 시간이 늘어납니다. 그러나 Wikipedia에 나열된 이점을 참조하는 경우 해당 기사는 전체 빌드, 패키징 및 배포 프로세스와 관련하여 관리 오버 헤드가 줄어드는 것에 대해 설명합니다.

C 및 C ++에서 인라인은 함수가 헤더 파일에 정의 된 경우에만 의미가 있습니다 *

이것은 컴파일러 / 링커 시스템에 달려 있지만 대부분의 기존 C 및 C ++ 컴파일러의 경우 이것이 맞습니다.

전통적으로 C에서는 .c / .h 레이아웃이 사용되었으며, 여기서 헤더는 번역 단위의 최소 공용 인터페이스를 나타냅니다. 마찬가지로 .cpp / hpp.

그것은 대부분 맞습니다. C ++ 클래스 헤더는 종종 최소 공용 인터페이스 이상을 포함합니다. 일반적으로 많은 개인 정보도 포함합니다. 이를 완화하기 위해 PIMPL 관용구 와 같은 것이 사용됩니다. 이것은 헤더 전용 라이브러리의 "반대"와 같은 것으로 필요한 헤더 내용을 최소화하려고합니다.

그러나 당신의 주요 질문에 대답하기 위해 : 이것은 절충입니다. 헤더 파일에 라이브러리 코드를 많이 넣을수록 컴파일러는 속도에 맞게 코드를 최적화 할 수있는 기회 가 많아 집니다 (실제로 발생하거나 증가가 눈에 띄면 완전히 다른 질문입니다). 반면 헤더에 코드가 너무 많으면 컴파일 시간이 길어집니다. 특히 대규모 C ++ 프로젝트에서는 심각한 문제가 될 수 있습니다. John Lakos의 "대규모 C ++ 소프트웨어 디자인"을 참조하십시오. 이 책은 약간 구식이며 여기에 설명 된 일부 문제는 최신 컴파일러, 일반적인 아이디어 / 솔루션은 여전히 ​​유효합니다.

특히, 안정적인 (타사) 라이브러리를 사용하지 않지만 프로젝트 중에 자체 라이브러리를 개발하는 경우 컴파일 시간이 분명해집니다. lib에서 무언가를 변경할 때마다 헤더 파일을 변경해야합니다. 그러면 모든 종속 장치가 다시 컴파일되고 연결됩니다.

헤더 전용 라이브러리의 인기는 템플릿 메타 프로그래밍의 인기로 인해 발생합니다. 대부분의 컴파일러의 경우 템플릿 매개 변수는 형식 매개 변수가 제공 될 때만 컴파일러가 기본 컴파일 프로세스를 시작할 수 있기 때문에 템플릿 전용 라이브러리 헤더 전용 이어야합니다. 전체 컴파일 및 최적화를 위해 컴파일러는 "한 번에 둘 다"-라이브러리 코드와 템플릿을 참조해야합니다. 매개 변수 값. 따라서 그러한 라이브러리에 대해 "사전 컴파일 된"컴파일 단위를 생성 할 수 없습니다 (적어도 어렵습니다).


6
간단히 말해 헤더 전용 라이브러리는 보다 효율적이 아니라보다 편리 합니다 . C ++에는 표준 패키지 관리자가 없기 때문에 채택 촉진에 도움이됩니다.
Matthieu M.

6
@MatthieuM : 아니요, 컴파일 된 코드가 실제로 더 효율적일 수 있으며 템플릿 라이브러리의 경우 헤더 전용 디자인은 일반적으로 편의의 문제가 아닙니다. 그리고 컴파일 시간을 늘리는 것이 더 편리하지는 않습니다.
Doc Brown

헤더에 핫 코드가 있으면 더 효율적으로 컴파일 된 코드가 생성 될 수 있지만 헤더에 모든 코드를 포함 할 필요 는 없으므로 헤더 전용 라이브러리와는 독립적입니다.
Matthieu M.

1
@MatthieuM .: 확실히 맞습니다. 그럼에도 불구하고 "더 편리한"이라는 용어는 그 경우를 잘 설명하지 못한다고 생각합니다.
Doc Brown

3
나는 이전 고용주를 위해 축소 된 구형 OS 위에서 대형 임베디드 프로젝트를 수행했으며 이러한 경우 긴 컴파일 시간의 고통을 증명할 수 있습니다. 헤더 파일에 너무 많은 것을 넣은 사람은 무자비하게 처리됩니다.
Fred Thomsen

15

먼저 몇 가지 가정을 철거합시다.

  1. C ++ 용 헤더 전용 라이브러리의 장점 중 하나는 별도로 컴파일 할 필요가 없다는 것입니다.

사물을 개별적으로 컴파일한다는 것은 부분 만 바뀌더라도 모든 것을 다시 컴파일 할 필요가 없다는 것을 의미합니다.
따라서 장점 대신 단점이 있습니다.

  1. C 및 C ++에서 인라인은 함수가 헤더 파일 *에 정의 된 경우에만 의미가 있습니다.

예, inline남은 유일한 효과 는 one-definition-rule 의 예외 입니다.
그래도 그 정의가 다르면 당신에게 화가납니다.

따라서 함수가 컴파일 단위 내부에 있으면 표시하십시오 static. 또한 인라인 기능을 사용할 수 있어야하므로 인라인 가능성이 높아집니다.
여전히 MSVC ++, gcc 및 clang에서 지원하는 링크 타임 최적화를 살펴보십시오.

  1. 전통적으로 C에서는 .c / .h 레이아웃이 사용되었으며, 여기서 헤더는 번역 단위의 최소 공용 인터페이스를 나타냅니다. 마찬가지로 .cpp / hpp.

글쎄, 최소한의 인터페이스 만 제시하는 것은 확실히 API 및 ABI 안정성을 높이고 컴파일 시간을 최소화하는 목표 중 하나입니다.

특히 C ++ 클래스는 모든 개인 비트가 헤더로 누출되므로 보호 된 클래스와 마찬가지로 헤더에서 누출되기 때문에 실제로 그에 맞게 조정되지 않았습니다.

디자인 패턴 PIMPL 은 이러한 세부 사항을 줄이기위한 것입니다.

C ++에서 인터페이스와 구현을 완전히 분리하지 못하는 부분은 템플릿입니다.
위원회는 내 보낸 템플릿으로 무언가를 시도했지만 너무 복잡하고 실제로 작동하지 않았습니다.

이제는 느리지 만 적절한 모듈 시스템 에서 작업하고 있습니다. 이는 컴파일 시간을 크게 줄이고, 표면을 줄여 API 및 ABI 안정성을 높여야합니다.

헤더 전용 라이브러리는 일반적으로 기존 레이아웃보다 코드 및 실행 시간이 더 효율적입니까? 그렇다면 광범위한 인라인 또는 기타 최적화로 인한 것입니까?

헤더 전용 라이브러리는 코드 크기 및 실행 시간이 더 효율적일 수 있지만 라이브러리 공유 여부, 사용 횟수, 방법 및 인라이닝이 특정 경우에 결정적인 승리를 나타내는 지 여부에 따라 다릅니다.

인라인 자체가 최적화에 중요한 이유는 인라인 자체가 크게 향상되지 않았기 때문에 지속적인 전파 및 추가 최적화 기회가 있기 때문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.