Pregunta

Tengo un psicológicos tic que me hace reacios a utilizar las bibliotecas de gran tamaño (como GLib o Boost) en el bajo nivel de lenguajes de programación como C y C++.En mi mente, pienso:

Bien, esta biblioteca cuenta con miles de horas hombre puso en él, y que ha sido creado por gente que sabe mucho más sobre el lenguaje de lo que yo alguna vez.Sus autores y sus seguidores dicen que las bibliotecas son rápidos y fiables, y la funcionalidad se ve realmente útil, y eso sin duda me pare a partir de (mal) la reinvención de ruedas.

Pero maldita sea, yo nunca voy a usar cada función en la biblioteca.Es demasiado grande y es probable que se hinchan a través de los años;es otra bola y la cadena de mi programa de necesidades para arrastrar alrededor.

El Torvalds despotricar (polémica a pesar de que es) no es exactamente a poner mi corazón en la facilidad cualquiera.

Hay alguna base para mi forma de pensar, o estoy simplemente irrazonable y/o ignorantes?Incluso si sólo lo uso una o dos características de una gran biblioteca, mediante la vinculación a que la biblioteca se me va a incurrir rendimiento en tiempo de ejecución de los gastos generales?

Estoy seguro de que depende demasiado de lo que la biblioteca específica, pero en general estoy interesado en saber si las grandes bibliotecas, a nivel técnico, inherentemente introducir ineficiencias.

Estoy cansado de obsesionar y murmurando y preocuparse por esto, cuando no tengo los conocimientos técnicos para saber si estoy en lo correcto o no.

Por favor, me puso fuera de mi miseria!

¿Fue útil?

Solución

  

Aunque yo sólo uso una o dos características de una gran biblioteca, mediante la vinculación a esa biblioteca voy a incurrir en los gastos generales de funcionamiento de tiempo de ejecución?

En general, no.

Si la biblioteca en cuestión no tiene una gran cantidad de código independiente de la posición, entonces habrá un costo de puesta en marcha, mientras que el enlazador dinámico lleva a cabo la reubicación de la biblioteca cuando es solicitado. Por lo general, eso es parte de la puesta en marcha del programa. No hay ningún efecto de rendimiento en tiempo de ejecución más allá de eso.

Los enlazadores también son buenos en la eliminación de "código muerto" de las librerías enlazadas estáticamente en tiempo de compilación, por lo que cualquier bibliotecas estáticas que utiliza tendrán un mínimo de gastos tamaño. Rendimiento ni siquiera entra en ella.

Francamente, estás preocuparse por las cosas equivocadas.

Otros consejos

No puedo hacer comentarios sobre GLib, pero tenga en cuenta que una gran parte del código en Boost es sólo de encabezado y teniendo en cuenta el principio de C ++ de que el usuario sólo paga por lo que están usando, las bibliotecas son bastante eficientes. Hay varias bibliotecas que le obliguen a vincular en contra de ellos (expresiones regulares, sistema de archivos vienen a la mente) pero son bibliotecas separadas. Con Boost no vincula en contra de una gran biblioteca monolítico, sino sólo contra los componentes más pequeños que usted hace uso.

Por supuesto, la otra pregunta es - ¿cuál es la alternativa? ¿Quieres poner en práctica la funcionalidad que se Boost en ti mismo cuando lo necesite? Dado que una gran cantidad de personas muy competentes han trabajado en este código y asegurado que funciona a través de una multitud de compiladores y todavía es eficiente, esto podría no ser exactamente una tarea sencilla. Además de que estés reinventar la rueda, al menos hasta cierto punto. En mi humilde opinión puede pasar este tiempo de manera más productiva.

Boost no es una gran biblioteca.

Se trata de una colección de muchas bibliotecas pequeñas. La mayoría de ellos son tan pequeños que están contenidos en un encabezado o dos. Usando boost::noncopyable no arrastra boost::regex o boost::thread en el código. Son diferentes bibliotecas. Sólo están distribuidos como parte de la misma colección de la biblioteca. Pero usted sólo paga por los que utiliza.

Sin embargo, en términos generales, ya que existen grandes bibliotecas, incluso si Boost no es uno de ellos:

  

¿Hay alguna base a mi forma de pensar, o estoy simplemente irracional y / o ignorantes? Incluso si sólo utilizo una o dos características de una gran biblioteca, mediante la vinculación a esa biblioteca voy a incurrir en los gastos generales de funcionamiento de tiempo de ejecución?

No se base, más o menos . Usted puede probar por sí mismo.

Escribir un pequeño programa en C ++ y compilarlo. Ahora añade una nueva función para él, uno que nunca se llama, sino que se define. Compilar el programa de nuevo. optimizaciones que asumen están habilitados, que se despojó a cabo por el enlazador porque es utilizada. Por lo que el costo de incluir adicional sin usar código es cero.

Por supuesto que hay excepciones. Si el código crea objetos globales, aquellos que no se pueden eliminar (por eso incluyendo la cabecera iostream aumenta el tamaño del ejecutable), pero en general, se pueden incluir tantas cabeceras y enlace a tantas bibliotecas como desee, y ganaron' t afectan el tamaño, el rendimiento o el uso de memoria de su programa *, siempre y cuando no lo hace utilizar cualquier parte del código añadido.

Otra excepción es que si se vincula dinámicamente a un .dll o .so, toda la biblioteca debe ser distribuida, por lo que no puede ser despojado de código no utilizado. Pero las bibliotecas que están compilado estáticamente en el ejecutable (ya sea como bibliotecas estáticas (.lib o .a) o simplemente como archivos de cabecera incluidos por lo general pueden ser recortados por el enlazador, la eliminación de los símbolos utilizados.

grande biblioteca, desde el código perspectiva de rendimiento:

  • ocupará más memoria , si tiene un tiempo de ejecución binaria (la mayor parte de boost no requieren que los binarios de tiempo de ejecución, que son "sólo de encabezado"). Mientras que el sistema operativo se carga sólo las partes realmente utilizadas de la biblioteca a la RAM, todavía puede cargar más de lo necesario, ya que la granularidad de lo que está cargado es igual al tamaño de página (4 KB en mi sistema, sin embargo).
  • tomar más tiempo para cargar por enlazador dinámico, si, una vez más, se necesita binarios de tiempo de ejecución. Cada vez que se carga el programa, enlazador dinámico tiene que coincidir con cada función que necesita biblioteca externa para contener con su dirección real en la memoria. Se necesita algún tiempo, pero sólo un poco (sin embargo, que importa en una escala de carga de muchos programas, como el inicio del entorno de escritorio, pero usted no tiene una opción allí).

    Y sí, se tardará un salto extra y un par de ajustes de puntero en tiempo de ejecución cada vez que se llama a la función externa de un compartida (enlace dinámico) de la biblioteca

de un del desarrollador perspectiva de rendimiento:

  • añadir una dependencia externa . Va a ser dependiendo de otra persona . Incluso si el software libre de esa biblioteca, tendrá un gasto extra para modificarlo. Algunos desarrolladores de programas veeery de bajo nivel (estoy hablando de granos OS) odian que depender de nadie - que es su ventaja profesional. Así, los rantes.

    Sin embargo, que puede ser considerado un beneficio. Si otras personas están acostumbrado a boost, encontrarán conceptos familiares y términos en su programa y serán comprensión más eficaz y modificándolo.

  • Las bibliotecas más grandes por lo general contienen conceptos de biblioteca específica que toman tiempo para entender. Considere Qt. Contiene señales y slots y la infraestructura relacionada con moc. En comparación con el tamaño de todo el Qt, aprendiendo los lleva a una pequeña fracción de tiempo. Pero si se utiliza una pequeña parte de una gran biblioteca de este tipo, que puede ser un problema.

El exceso de código no mágicamente hacer funcionar el procesador más lento. Todo lo que hace es sentarse allí ocupando un poco de memoria.

Si está estáticamente la vinculación y el enlazador es en absoluto razonable, entonces será sólo incluyen las funciones que realmente utiliza de todos modos.

El término que me gusta de los marcos, juegos de la biblioteca, y algunos tipos de herramientas de desarrollo, es tecnologías de plataforma. tecnologías de plataforma tienen costos más allá de impacto en el tamaño del código y el rendimiento.

  1. Si su proyecto está destinado sí para ser utilizado como una biblioteca o un marco, que puede terminar empujando sus opciones de tecnología de plataforma de desarrolladores que utilizan la biblioteca.

  2. Si distribuye su proyecto en forma de código fuente, que puede terminar empujando opciones tecnológicas plataforma en la que los usuarios finales.

  3. Si no lo hace de forma estática enlazar todas sus marcos escogidos y bibliotecas, que puede terminar una carga para sus usuarios finales con los problemas de versiones de la biblioteca.

  4. Tiempo de compilación productividad efectos desarrollador. la vinculación incremental, encabezados precompilados, el manejo adecuado de dependencia de cabecera, etc., pueden ayudar a controlar los tiempos de compilación, pero no eliminan los problemas de rendimiento asociados con el compilador de las enormes cantidades de código en línea algunas tecnologías de plataforma introducen.

  5. Para los proyectos que se distribuyen de la fuente, el tiempo de compilación afecta a los usuarios finales del proyecto.

  6. Muchas de las tecnologías de plataforma tienen sus propios requisitos del entorno de desarrollo. Estos requisitos se pueden acumular por lo que es difícil y requiere mucho tiempo para los nuevos desarrolladores en un proyecto para poder replicar el entorno necesario para permitir la compilación y depuración.

  7. El uso de algunas tecnologías de plataforma en efecto crea un nuevo lenguaje de programación para el proyecto. Esto hace que sea más difícil para los nuevos desarrolladores para contribuir.

Todos los proyectos tienen dependencias de tecnología de plataforma, pero para muchos proyectos hay beneficios reales para mantener estas dependencias al mínimo.

Puede haber una pequeña sobrecarga al cargar estas bibliotecas si están muy relacionados entre sí. Esto normalmente será una pequeñísima fracción del tiempo que gasta su programa en ejecución,.

Sin embargo, no habrá gastos indirectos una vez que todo está cargado.

Si no desea utilizar todos de impulso, entonces no. Es modular, lo que puede utilizar las partes que desee e ignorar el resto.

Más grande no implica inherentemente más lento.Contrariamente a algunas de las otras respuestas, no hay diferencia significativa entre las bibliotecas almacenan enteramente en las cabeceras y las bibliotecas almacenan en archivos objeto cualquiera.

Solamente de cabecera bibliotecas puede tiene una ventaja indirecta.La mayoría de la plantilla basada en las bibliotecas tienen que ser solamente de cabecera (o un mucho de el código termina en los encabezados de todos modos), y plantillas de hacer dar un montón de oportunidades para la optimización.Tomando el código en un típico objeto-biblioteca de archivos y mover todo en los encabezados no, sin embargo , por lo general tienen muchos buenos efectos (y puede conducir a código de engordar).

La verdadera respuesta para una biblioteca particular en general dependerá de su estructura general.Es fácil pensar en el "Impulso" como algo enorme.De hecho, es un gran colección de las bibliotecas, la mayoría de los cuales son individualmente muy pequeño.No se puede decir mucho (de manera significativa) sobre Impulso como un todo, porque el individuo que las bibliotecas son escritos por diferentes personas, con diferentes técnicas, objetivos, etc.Algunos de ellos (por ejemplo,Formato de Asignar) son realmente más lento que el de casi cualquier cosa que usted estaría muy probable de hacer en su propio.Otros (por ejemplo,La piscina) proporcionar cosas que usted podría hacer por sí mismo, pero probablemente no, para conseguir, al menos, de menor importancia de las mejoras de velocidad.Algunos (por ejemplo,uBlas) el uso pesado de la plantilla de la magia de correr más rápido que cualquier pero un pequeño porcentaje de nosotros puede aspirar a lograr por nuestra cuenta.

Hay, por supuesto, un buen número de bibliotecas que realmente son individualmente las grandes bibliotecas.En muy pocos casos, estos son realmente más lento que lo que iba a escribir.En particular, muchos (la mayoría?) de ellos intento de ser mucho más general que el de casi cualquier cosa que usted estaría en todos los propensos a escribir en su propia.Mientras que no necesariamente conducir más lento el código, definitivamente hay un fuerte la tendencia en esa dirección.Como con un montón de código, cuando estamos desarrollando bibliotecas comercialmente, los clientes tienden a ser mucho más interesado en las funciones que cosas como el tamaño de la velocidad.

Algunas bibliotecas también dedican un montón de espacio, de código (y, a menudo, al menos bits de tiempo) a la solución de los problemas que pueden muy bien no le importa en absoluto.Así por ejemplo, los años he usado una biblioteca de procesamiento de imagen.Su apoyo a más de 200 formatos de imagen sonaba realmente impresionante (y de una manera que realmente era), pero estoy bastante seguro de que nunca la utilizó para lidiar con más de una docena de formatos (y probablemente podría haber conseguido por apoyar solamente la mitad de los muchos).OTOH, incluso con todo lo que era todavía bastante rápido.Apoyar a menos que los mercados podrían haber restringido su mercado hasta el punto de que el código en realidad hubieran sido más lento (por ejemplo, manejado Jpeg más rápido que IJG).

Como otros han dicho, hay algo de sobrecarga cuando la adición de una biblioteca dinámica. Cuando se carga por primera vez la biblioteca, las reubicaciones deben llevarse a cabo, aunque esto debe ser un costo menor si la biblioteca se compila correctamente. El costo de buscar símbolos individuales también se incrementa ya que el número de bibliotecas que necesitan ser buscado se incrementa.

El coste en memoria de la adición de otra biblioteca dinámica depende en gran medida de cuánto de lo que realmente utiliza. Una página de código no se carga desde el disco hasta que se ejecuta algo en él. Sin embargo, se cargarán otros datos como encabezados, tablas de símbolos, y tablas hash incorporados en el archivo de la biblioteca, y estos son generalmente proporcional al tamaño de la biblioteca.

Hay una gran documento de Ulrich Drepper, el contribuyente principal a glibc, que describe el proceso y la sobrecarga de las bibliotecas dinámicas.

depende de cómo funciona el enlazador. Algunos enlazadores son perezosos e incluirán todo el código en la biblioteca. Los enlazadores más eficientes sólo extraer el código necesario de una biblioteca. He tenido experiencia con ambos tipos.

Las bibliotecas más pequeñas tendrán menos preocupaciones con cualquier tipo de enlazador. Peor de los casos con una pequeña biblioteca es una pequeña cantidad de código no utilizado. Muchas bibliotecas pequeñas pueden aumentar el tiempo de construcción. El descuento comercial sería construir tiempo frente a espacio de código.

Una prueba interesante del enlazador es el clásico Hello World programa:

#include <stdio>
#include <stdlib>
int main(void)
{
  printf("Hello World\n");
  return EXIT_SUCCESS;
}

La función printf tiene un gran número de dependencias debido a todo el formato que puede necesidad. Un enlazador perezoso, pero rápido puede incluir una "biblioteca estándar" para resolver todos los símbolos. Una biblioteca más eficiente sólo incluirá printf y sus dependencias. Esto hace que el enlazador más lento.

El programa anterior se puede comparar con éste usando puts:

#include <stdio>
#include <stdlib>
int main(void)
{
  puts("Hello World\n");
  return EXIT_SUCCESS;
}

Generalmente, la versión puts debe ser menor que la versión printf, porque puts no tiene necesidades del formato por lo tanto menos dependencias. enlazadores Lazy generarán el mismo tamaño de código como el programa printf.

En resumen, decisiones sobre el tamaño de la biblioteca tienen más dependencias en el enlazador. Específicamente, la eficiencia del enlazador. En caso de duda, muchas bibliotecas pequeñas serán depender menos de la eficiencia del enlazador, pero hacer que el proceso de construcción más complicado y más lento.

  1. Lo que hay que ver con los problemas de rendimiento, en general, no es para entretener a ellos, porque hacerlo es ser adivinando que son un problema, porque si no lo hace saben que son, que está adivinando, y adivinar es el concepto central detrás de "optimización prematura". Lo que hay que ver con los problemas de rendimiento es, cuando las tenga, y no antes , diagnosticarlos. Los problemas son casi nunca es algo que se hubiera imaginado. He aquí un ejemplo ampliado.

  2. Si lo hace una buena cantidad, se llega a reconocer los enfoques de diseño que tienden a causar problemas de rendimiento, ya sea en el código o en una biblioteca. (Las bibliotecas pueden ciertamente tener problemas de rendimiento.) Cuando se entera de que y aplicarlo a proyectos a continuación, en un sentido que están optimizando de forma prematura, pero tiene el efecto deseado de todos modos, de evitar problemas. Si puedo resumir lo que es probable que aprender, es que demasiadas capas de abstracción, y las jerarquías de clase exageradas (especialmente aquellos completa de actualización de estilo notificación) son lo que son muy a menudo las razones de los problemas de rendimiento.

Al mismo tiempo, me dé su circunspección acerca de las bibliotecas 3 ª parte y tal. Demasiadas veces he trabajado en proyectos en los que algún paquete tercero-partido fue "apalancamiento" de "sinergia", y luego el vendedor o bien se convirtieron en humo o abandonados el producto o tenían que ir obsoleta, ya que Microsoft cambió las cosas en el sistema operativo. Luego de que nuestro producto se apoyó en gran medida en el paquete tercero-partido no comienza a trabajar, lo que requiere un gran gasto de nuestra parte, mientras que los programadores originales han quedado atrás.

"otra bola y la cadena". ¿En serio?

O es una plataforma estable y fiable que permite su aplicación en el primer lugar?

Tenga en cuenta que algunas personas pueden como un "demasiado grandes y ... hinchada" biblioteca porque lo usan para otros proyectos y realmente confían en él.

De hecho, pueden negarse a meterse con su software específicamente debido a que evitó el uso de lo obvio "demasiado grandes y ... hinchada" biblioteca.

Técnicamente, la respuesta es que sí, que lo hacen. Sin embargo, estas ineficiencias son muy rara vez importante en la práctica. Voy a asumir un lenguaje compilado estáticamente como C, C ++, o D aquí.

Cuando un ejecutable se carga en memoria en un sistema operativo moderno, espacio de direcciones es simplemente asignada a la misma. Esto significa que, no importa cuán grande es el exectable es, si hay bloques de la página de tamaño enteros de código que no se usan, ellos nunca tocan la memoria física. Va a desperdiciar espacio de direcciones, sin embargo, y en ocasiones esto puede importar un poco en sistemas de 32 bits.

Cuando se vincula a una biblioteca, un buen enlazador generalmente tirar el exceso de material que no se utiliza, aunque especialmente en el caso de las instanciaciones de plantillas esto no siempre sucede. Por lo tanto los binarios podrían ser un poco más grande de lo estrictamente necesario.

Si tiene código que no se utiliza en gran medida intercalada con el código que usted utilice, puede acabar perdiendo espacio en la memoria caché de la CPU. Sin embargo, como líneas de caché son pequeñas (generalmente 64 bytes), esto rara vez ocurre en un grado importante en la práctica.

Pregúntese cuál es su objetivo. Es una estación de trabajo final a mediados de hoy - no hay problema. Es hardware antiguo o incluso un sistema embebido limitado, entonces podría ser.

Como críticos anteriores han dicho, sólo tener el código de allí no le costará mucho en el rendimiento (que podría reducir la localidad por los cachés y aumentar los tiempos de carga).

fwiw, trabajo en Microsoft Windows y cuando construimos de Windows; build compilado por Tamaño son más rápidos que construye compilado por VELOCIDAD porque se toman menos culpa página encontrados.

FFTW y ATLAS son dos bibliotecas bastante grandes. Por extraño que parezca, juegan grandes papeles en el software más rápido en el mundo, las aplicaciones optimizadas para funcionar en superordenadores. No, el uso de grandes bibliotecas no hace que su código lento, especialmente cuando la alternativa es implementar FFT o rutinas BLAS por sí mismo.

mucha razón para estar preocupado, sobre todo cuando se trata de impulsar. No es tanto debido a cualquiera de escribirlas ser incompetentes, pero debido a dos cuestiones.

  1. Plantillas son sólo código inherentemente hinchado. Este no importaba tanto como hace 10 años, pero hoy en día la CPU es mucho más rápido que el acceso a la memoria y esta tendencia continúa. Casi diría que las plantillas son una característica obsoleta.

No es tan malo para el código de usuario, que suele ser algo práctico, pero en muchas bibliotecas de todo lo que se define en términos de otras plantillas o plantilla de en varios elementos (es decir explosiones código de la plantilla exponencial).

La simple adición de iostream añade alrededor de 3 mb (!!!) a su código. Ahora añade en una cierta alza sin sentido y tiene 30 MB de código si Sinply declarar un par de estructuras de datos particularmente extraños.

Peor aún, no se puede mostrar el perfil siquiera esto fácilmente. Te puedo decir la diferencia entre el código escrito por mí y el código de bibliotecas de plantillas es dramático, pero para un enfoque más naieve usted puede pensar que está haciendo peor de una prueba simple, pero el costo en exceso de código a tomar su herramienta en un gran mundo real aplicación.

  1. Complejidad. Cuando nos fijamos en las cosas en Boost, que son todas las cosas que complican su código a un grado enorme. Cosas como punteros inteligentes, funtores, todo tipo de cosas complicadas. Ahora, no voy a decir que nunca es una buena idea usar estas cosas, pero casi toda ella tiene un gran coste de algún tipo. Especialmente si usted no entiende exactamente, quiero decir exactamente, lo que está haciendo.

Pero la gente hablar sobre ello y pretender que tiene algo que ver con el 'diseño' para que la gente tiene la impresión de que es la forma en que debe hacerlo todo, no sólo algunas herramientas muy especializadas que deben ser utilizados raramente. Si alguna vez.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top