As bibliotecas somente de cabeçalho são mais eficientes?

38

Suposições

  1. Uma das vantagens das bibliotecas somente de cabeçalho para C ++ é que elas não precisam ser compiladas separadamente.

  2. Em C e C ++ inline faz sentido apenas se a função estiver definida em um arquivo de cabeçalho *.

  3. Tradicionalmente, em C, o layout .c / .h foi usado, onde o cabeçalho representa a interface pública mínima da unidade de tradução. Da mesma forma, .cpp / hpp.

Pergunta

As bibliotecas somente de cabeçalho geralmente são mais eficientes em termos de código e execução do que o layout tradicional? Em caso afirmativo, isso ocorre devido a inlining extensivo ou outras otimizações?

* - definir a função em um cabeçalho permite ao compilador ver a implementação durante a compilação de qualquer unidade de tradução e praticamente torna possível o código inlining

    
por Vorac 22.12.2015 / 08:22
fonte

2 respostas

39

One of the advantages of header-only libraries for C++ is that they do not need to be compiled separately

Não, isso não é uma vantagem, muito pelo contrário - a parte principal da biblioteca tem que ser compilada sempre que incluída, não apenas uma vez. Isso normalmente aumentará os tempos de compilação. No entanto, se você está se referindo às vantagens listadas aqui na Wikipedia : esse artigo está falando sobre a redução da sobrecarga administrativa em relação à todo o processo de construção, embalagem e implantação.

In C and C++ inline makes sense only if the function is defined in a header file*

Isso depende do sistema compilador / linker, mas acho que para a maioria dos compiladores C e C ++ existentes isso é verdade.

Traditionally, in C, .c/.h layout has been used, where the header represents the minimal public interface of the translation unit. Similarly, .cpp/hpp.

Isso está correto na maior parte. Os cabeçalhos de classe C ++ geralmente contêm mais do que a interface pública mínima - eles normalmente contêm também muitas coisas particulares. Para atenuar isso, coisas como o idioma PIMPL são usadas. Isso é algo como "o oposto" de uma biblioteca somente de cabeçalho, que tenta minimizar o conteúdo do cabeçalho necessário.

Mas, para responder à sua pergunta principal: isso é um compromisso. Quanto mais código de biblioteca se coloca nos arquivos de cabeçalho, mais o compilador tem uma chance para otimizar o código para velocidade (se isso realmente acontecer, ou se o aumento for notável, é uma questão completamente diferente) . Por outro lado, código excessivo nos cabeçalhos aumenta o tempo de compilação. Especialmente em grandes projetos em C ++, isso pode se tornar um problema sério, veja "Design de Software em Cálculo em Grande Escala", de John Lakos - Embora o livro esteja um pouco desatualizado e alguns dos problemas descritos nele sejam abordados por compiladores modernos, as idéias / soluções gerais ainda são válidas.

Em particular, quando você não está usando uma biblioteca estável (de terceiros), mas você está desenvolvendo suas próprias bibliotecas durante o seu projeto, os tempos de compilação se tornam aparentes. Toda vez que você mudar alguma coisa na lib, você deve alterar um arquivo de cabeçalho, o que causará uma recompilação e uma ligação de todas as unidades dependentes.

IMHO a popularidade das bibliotecas somente de cabeçalho é causada pela popularidade da metaprogramação de modelos. Para a maioria dos compiladores, as bibliotecas templated devem ser somente cabeçalho porque o compilador só pode iniciar o processo de compilação principal quando os parâmetros de tipo são fornecidos, e para compilação e otimização completa o compilador deve ver "both at once" - o código da biblioteca mais os valores dos parâmetros do modelo. Isso torna impossível (ou pelo menos difícil) produzir quaisquer unidades de compilação "pré-compiladas" para essa biblioteca.

    
por 22.12.2015 / 08:44
fonte
13

Bem, primeiro vamos demolir algumas de suas suposições:

  1. One of the advantages of header-only libraries for C++ is that they do not need to be compiled separately.

Compilar as coisas separadamente significa potencialmente não ter que recompilar tudo se apenas uma parte for alterada.
Então, uma desvantagem em vez de uma vantagem.

  1. In C and C++ inline makes sense only if the function is defined in a header file*.

Sim, o único efeito que inline deixou é a exceção à regra de uma única definição .
Ai de você, se essas definições são diferentes de qualquer maneira embora.

Portanto, se uma função for interna a uma unidade de compilação, marque-a como static . Isso também torna mais provável o inlining, já que a função precisa estar disponível para inline-lo.
Ainda assim, dê uma olhada na otimização do link-time, como suportada pelo menos pelo MSVC ++, gcc e clang.

  1. Traditionally, in C, .c/.h layout has been used, where the header represents the minimal public interface of the translation unit. Similarly, .cpp/hpp.

Bem, apenas apresentar a interface mínima é certamente um dos objetivos, para alcançar maior estabilidade API e ABI, e para minimizar os tempos de compilação.

Especialmente, as classes C ++ não são realmente voltadas para isso, já que todos os bits privados vazam para o cabeçalho, assim como os protegidos, quer você queira derivar dele ou não.

O padrão de design PIMPL é para reduzir tais detalhes.

A parte em que a interface e a implementação de separação falha completamente em C ++ é um modelo.
O comitê tentou fazer algo com modelos exportados , mas isso foi abandonado por ser muito complicado e realmente não funciona.

Agora, eles estão trabalhando em um sistema de módulos adequado , embora seja lento. Isso reduz drasticamente os tempos de compilação e também deve aumentar a estabilidade da API e do ABI diminuindo sua superfície.

Are header-only libraries generally more efficient code- and execution time wise than the traditional layout? If so, is this because of extensive inlining or other optimizations?

Bibliotecas somente de cabeçalho podem ser mais eficientes em tamanho de código e tempo de execução, embora isso dependa de se a biblioteca é compartilhada, quanto dela é usada, de que maneira, e se o inlining prova uma vitória decisiva nesse caso específico.

E a razão pela qual o inline é tão importante para a otimização não é porque o próprio inline é um grande impulso, mas devido às oportunidades de propagação constante e otimização adicional, ele é aberto.

    
por 22.12.2015 / 11:55
fonte

Tags