Trabajo para una empresa que tiene un departamento de "middleware" propio para mantener unos pocos cientos de bibliotecas que son comúnmente utilizadas por un gran número de equipos.
A pesar de estar en la misma compañía, nos rehuimos del enfoque de encabezado único y preferimos favorecer la compatibilidad binaria sobre el rendimiento debido a la facilidad de mantenimiento.
El consenso general es que la ganancia de rendimiento (si hay alguna) no valdría la pena.
Además, el llamado "blob de código" puede tener un impacto negativo en el rendimiento ya que más código que se cargará en la caché implica más falta de memoria caché, y esos son los asesinos de rendimiento.
En un mundo ideal, supongo que el compilador y el enlazador podrían ser lo suficientemente inteligente como para no generar esas reglas "múltiples definiciones", pero siempre y cuando no es el caso, lo que favorecerá (personalmente):
- compatibilidad binaria
- no inlining (por métodos que son más de un par de líneas)
¿por qué no probar? Prepare las dos bibliotecas (un encabezado solo y el otro sin incluir métodos en un par de líneas) y verifique su desempeño respectivo en SU CASO.
EDIT:
Se ha señalado por 'JALF' (gracias) que debería precisa lo que significa exactamente la compatibilidad binaria.
Se dice que 2 versiones de una biblioteca determinada son compatibles con binario si puede (normalmente) vincularse una u otra sin ningún cambio de su propia biblioteca.
Como solo se puede vincular con una versión de una biblioteca determinada Target
, todas las bibliotecas cargadas que usan Target
utilizarán efectivamente la misma versión ... y aquí está la causa de la transitividad de esta propiedad.
MyLib --> Lib1 (v1), Lib2 (v1)
Lib1 (v1) --> Target (v1)
Lib2 (v1) --> Target (v1)
Ahora, decir que necesitamos una solución en Target
para una característica única utilizada por Lib2
, entregamos una nueva versión (v2)
.Si (v2)
es compatible a nivel binario con (v1)
, entonces no podemos hacer:
Lib1 (v1) --> Target (v2)
Lib2 (v1) --> Target (v2)
Sin embargo, si no es el caso, entonces tendremos:
Lib1 (v2) --> Target (v2)
Lib2 (v2) --> Target (v2)
Sí, has leído bien, a pesar de que Lib1
hicieron no se requiere la revisión, se dirige a reconstruirlo en contra de una nueva versión de Target
ya que esta versión es obligatorio para el Lib2
actualizada y Executable
sólo puede enlazar con una versión de Target
.
Con una biblioteca sólo de encabezado, ya que no cuenta con una biblioteca, no son efectivamente compatible a nivel binario. Por lo tanto, cada vez que realice una reparación (seguridad, error crítico, etc.) deberá entregar una nueva versión y todas las bibliotecas que dependan de usted (incluso de forma indirecta) tendrán que reconstruirse con esta nueva versión.
¿Cómo Sólo encabezado libs implica código hinchazón? El compilador generalmente no se alineará si significa un código significativamente más grande. Y, para el caso, ¿cómo se ve afectada la compatibilidad binaria por libs de solo encabezado? – jalf
@Matthieu: Las pruebas siempre son buenas para determinar cuál arrojaría los mejores resultados. – DrYak
@Jalf: *** 1. Escenario solo de encabezado: para cada cambio en la biblioteca, una actualización de la biblioteca significa recompilar cada último proyecto que tiene dependencia de él. (Piense en la situación de Matthieu: cientos de bibliotecas, muchos equipos, muchas recompilaciones involucradas). *** 2. escenario binario único: para muchos cambios diferentes, una actualización simplemente implicará descartar un nuevo archivo .SO o .DLL, siempre que el ABI siga siendo el mismo. Aunque la nueva característica podría cambiar las firmas de métodos y estructuras de datos, las actualizaciones críticas (seguridad o estabilidad) raramente lo hacen. – DrYak