2011-03-24 14 views
5

No estoy seguro de si esta es una comparación válida o válida pero a lo largo de los años he escuchado que los programas escritos en C++ tardan más en compilarse que lo mismo escrito en C y que las aplicaciones codificadas en C++ son generalmente más lentas en tiempo de ejecución que las escritas en C.
¿Hay algo de verdad en estas afirmaciones?
Además de cosechar los beneficios de la flexibilidad de OOP que brinda C++, ¿se debe considerar la comparación anterior únicamente desde la perspectiva del tiempo de compilación/ejecución?Tiempo de compilación y ejecución de código fuente C++ vs C

Espero que esto no se cierre como demasiado genérico o vago, es sólo un intento de conocer los hechos reales sobre las declaraciones que he estado escuchando a lo largo de los años de muchos programadores (predominantemente programadores C).

+0

Creo que un poco de búsqueda en Google dará diez mil visitas sobre este tema, incluidos numerosos ensayos y trabajos de investigación. – Lundin

+4

@Lundin: admiro que SO tenga un grupo excelente de expertos que ofrezcan valiosos consejos y recomendaciones basados ​​en sus experiencias personales y profesionales. No se usaría SO si uno tuviera que buscar en Google y leer decenas y miles de ensayos en lugar de beneficiarse de las experiencias de otros programadores expertos. –

+0

El problema con esta pregunta es "el mismo programa en C". El problema es que ingenuamente implementar el mismo programa en C no le da el mismo programa. El compilador de C++ genera mucho más código que no ve realmente que el programador "C" debería implementar para que los programas sean iguales. Por lo tanto, debe agregar una tercera medida subjetiva a su prueba. ¿Cuánto tiempo lleva 'escribir' un programa equivalente de C++/C? Dada una aplicación no trivial, sospecho que la diferencia es significativa. –

Respuesta

9

Responderé a una parte específica de la pregunta que es bastante objetiva. El código C++ que usa plantillas va a ser más lento de compilar que el código C. Si no usa plantillas (que probablemente usará si usa la biblioteca estándar), debería ser un tiempo de compilación muy similar.

EDITAR: En términos de tiempo de ejecución, es mucho más subjetivo. Aunque C puede ser un lenguaje de un nivel algo inferior, los optimizadores de C++ se están volviendo realmente buenos, y C++ se presta a conceptos de mundo real que representan más naturalmente. Si es más fácil representar sus requisitos en el código (como diría en C++) a menudo es más fácil escribir un código mejor (y más eficiente) que en otro idioma. No creo que haya datos objetivos que muestren que C o C++ sean más rápidos en todos los casos posibles. En realidad, te sugiero elegir tu idioma según las necesidades del proyecto y luego escribirlo en ese idioma. Si las cosas son demasiado lentas, perfile y proceda con técnicas normales de mejora del rendimiento.

+0

Sí, es comprensible en el caso de las plantillas como compiladores necesita para generar las especializaciones. –

+0

La plantilla también puede aumentar el tiempo de ejecución en algún caso extremo debido a la sobreinflación (la plantilla tiende a alentar la creación ya que todo el código debe estar disponible en el encabezado) y/o debido al aumento del tamaño del código (cuando no están en línea y el enlazador no lo suficientemente inteligente como para fusionar la función correspondiente a la creación de instancias diferentes de la plantilla pero generando el mismo código, piense 'std :: vector < int* >' y 'std :: vector < float* >') que puede causar más falta de caché. –

+0

@Sylvain - ¿Cómo te podría ayudar escribir eso en C? –

-2

Las aplicaciones C son más rápidas de compilar y ejecutar que las aplicaciones C++.

Las aplicaciones C++ son generalmente más lentas en el tiempo de ejecución, y son mucho más lentas en compilar que los programas C.

mirada a estos enlaces:

+4

Me resulta difícil creer que "las aplicaciones C++ son generalmente más lentas en el tiempo de ejecución". ¿Tienes alguna evidencia para esta declaración? –

+0

Algunos de esos artículos tienen entre 5 y 10 años. Poco relevante más. –

+0

@Bo ¿Por qué? El último estándar C fue lanzado hace 12 años y el último estándar C++ fue lanzado hace 8 años. Estoy bastante seguro de que no ha habido ningún cambio revolucionario en la eficiencia general del compilador desde entonces. – Lundin

6

El tiempo de ejecución de C++ en comparación con C sufriría sólo si se utiliza cierta C++ - características específicas. Las excepciones y las llamadas a funciones virtuales se agregan al tiempo de ejecución en comparación con la devolución del código de error y las llamadas directas. Por otro lado, si te encuentras usando punteros a función en C (como, digamos, GTK), ya estás pagando al menos parte del precio de las funciones virtuales. Y consultar el código de error después de cada devolución de función también consumirá tiempo; no lo haces cuando usas excepciones.

Por otro lado, la alineación y las plantillas en C++ pueden permitirle hacer mucho trabajo en tiempo de compilación, trabajo que C difiere al tiempo de ejecución. En algunos casos, C++ puede terminar más rápido que C.

+0

Si se usa solo cuando corresponda, las excepciones generalmente darán como resultado en un código (muy ligeramente) más rápido que los códigos de retorno. –

4

Si compila el mismo código que C y C++, no debería haber diferencia.

Si deja que el compilador haga el trabajo por usted, como expandir plantillas, eso llevará algo de tiempo. Si haces lo mismo en C, con cortar y pegar o algunas macros intrincadas, tomará tu tiempo en su lugar.

En algunos casos, la expansión en línea de las plantillas realmente dará como resultado un código que es más especializado y ejecuta más rápido que el código C equivalente. Como aquí:

http://www2.research.att.com/~bs/new_learning.pdf

O este informe que muestra que muchas características de C++ tienen ningún coste en tiempo de ejecución:

http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf

+0

El problema es "El mismo código". Escribir el mismo código en C ejecutado por un programa C++ requiere que el ingeniero escriba significativamente más código fuente C (debido a las características adicionales del lenguaje). Entonces, la prueba del "mismo código" es muy subjetiva cuando se trata de un programa no trivial. –

+0

@Loki Astari: Viejo comentario, lo sé, pero Bo probablemente significaba literalmente el mismo código, por ejemplo. los mismos archivos, una vez compilados como C++ por g ++ y una vez por c por gcc (por supuesto, eso solo es posible si está escrito en la intersección de c y C++). – MikeMB

+0

@MikeMB: Entonces solo está escribiendo C. Claro, si escribe C y lo compila con g ++ y gcc, obtendrá el mismo código. Pero hace que la pregunta no sea interesante en absoluto si miras de esa manera. –

9

La velocidad relativamente tiempo de ejecución es un poco difícil de predecir. En un momento, cuando la mayoría de la gente pensaba en C++ como herencia, y usaba funciones virtuales lote (incluso cuando no eran particularmente apropiadas), el código escrito en C++ era típicamente un poco más lento que el equivalente C.

Con (lo que la mayoría de nosotros consideraríamos) C++ moderno, sucede lo contrario: las plantillas ofrecen suficiente flexibilidad en tiempo de compilación que puede producir código notablemente más rápido que cualquier equivalente razonable en C. En teoría, podría siempre evite eso escribiendo un código especializado equivalente al resultado de "expandir" una plantilla, pero en realidad, hacerlo es extremadamente raro y bastante caro.

Hay algo de una tendencia para C++ para escribir un poco más en general, así - sólo por ejemplo, la lectura de datos en std::string o std::vector (o std::vector<std::string>) por lo que el usuario puede introducir una cantidad arbitraria de datos sin desbordamiento de búfer o los datos simplemente se truncarán en algún punto. En C es lote más común ver a alguien simplemente codificar un búfer de tamaño fijo, y si ingresa más, se desborda o trunca. Obviamente, pagas algo por eso: el código C++ generalmente termina usando la asignación dinámica (new), que suele ser más lenta que la simple definición de una matriz. OTOH, si escribes C para lograr lo mismo, terminas escribiendo una gran cantidad de código adicional, y generalmente se ejecuta aproximadamente a la misma velocidad que la versión de C++.

En otras palabras, es bastante fácil escribir C que es notablemente más rápido para cosas como puntos de referencia y utilidades de un solo uso, pero la ventaja de velocidad se evapora en un código real que tiene que ser robusto. En este último caso, lo mejor que generalmente se puede esperar es que el código C sea equivalente a una versión C++, y honestamente, incluso hacerlo bien es bastante inusual (al menos IME).

Comparar la velocidad de compilación no es más fácil. Por un lado, es absolutamente cierto que las plantillas pueden ser lentas, al menos con la mayoría de los compiladores, la creación de instancias de plantillas es bastante costosa. En línea por línea, no hay duda de que C casi siempre será más rápido que cualquier cosa en C++ que use plantillas mucho. El problema con eso es que una comparación línea por línea raramente tiene mucho sentido: 10 líneas de C++ pueden ser fácilmente equivalentes a cientos o incluso miles de líneas de C. Siempre que mires solo en tiempo de compilación (no tiempo de desarrollo), la balanza probablemente favorece a C de todos modos, pero ciertamente no por un margen tan dramático como podría parecer inicialmente. Esto también depende en gran medida del compilador: solo por ejemplo, clang hace un lote mejor que gcc en este aspecto (y gcc también ha mejorado mucho en los últimos años).

2

Aunque es una vieja pregunta, me gustaría agregar mis 5cents aquí, ya que probablemente no sea el único que encuentre esta pregunta a través de un motor de búsqueda.

que no puedo comentar sobre la velocidad de compilación, sino en la velocidad de ejecución:

A lo mejor de mi conocimiento, no es sólo una característica de C++ que cuesta el rendimiento, incluso si no lo utiliza. Esta característica son las excepciones de C++, porque evitan algunas optimizaciones del compilador (esta es la razón por la cual se introdujo noexcept en C++ 11). Sin embargo, si utiliza algún tipo de mecanismo de comprobación de errores, entonces las excepciones son probablemente más eficientes que la combinación de verificación de valor de retorno y muchas declaraciones if else. Esto es especialmente cierto, si tiene que escalar un error en la pila.

De todos modos, si desactivas las excepciones durante la compilación, C++ no introduce sobrecarga, excepto en los lugares donde utilizas deliberadamente las funciones asociadas (por ejemplo, no tienes que pagar por el polimorfismo si no usas funciones virtuales), mientras que la mayoría de las características no introducen ningún tipo de sobrecarga de tiempo de ejecución (sobrecarga, plantillas, espacios de nombres, etc.). Por otro lado, la mayoría de las formas de código genérico serán mucho más rápidas en C++ que el equivalente en c, porque C++ proporciona los mecanismos incorporados (plantillas y clases) para hacer esto. Un ejemplo típico es cs qsort vs C++ 's std :: sort. La versión de C++ suele ser mucho más rápida, porque dentro de la clasificación, la función de comparador utilizado se conoce en tiempo de compilación, que al menos guarda una llamada a través de una función de búsqueda y en el mejor de los casos permite una gran cantidad de optimizaciones de compilación adicionales.

Habiendo dicho eso, el "problema" con C++ es que es fácil ocultar la complejidad del usuario de modo que un código aparentemente inocente podría ser mucho más lento de lo esperado. Esto se debe principalmente a la sobrecarga del operador, el polimorfismo y los constructores/destructores, pero incluso una simple llamada a una función miembro oculta el this -pointer pasado que tampoco es un NOP. Considerando la sobrecarga del operador: cuando ve un * en c, sabe que esto es (en la mayoría de las arquitecturas) una instrucción de ensamblador única y barata, en C++ por otro lado puede ser una función compleja (piense en la multiplicación de matrices). Eso no significa que pueda implementar la misma funcionalidad en c más rápido, pero en C++ no ve directamente que esto podría ser una operación costosa. Destructors son un caso similar: en C++ "moderno", apenas verá destrucciones explícitas a través de supresión pero cualquier variable local que salga del alcance podría desencadenar una costosa llamada a un destructor (virtual) sin una sola línea de código que indica esto (ignorando } por supuesto). Y, por último, algunas personas (especialmente las procedentes de Java) tienden a escribir jerarquías de clases complejas con muchas funciones virtuales, donde cada llamada a dicha función es una llamada de función indirecta oculta que es difícil o imposible de optimizar. Por lo tanto, aunque esconder la complejidad del programador es, en general, algo bueno que a veces tiene un efecto adverso en el tiempo de ejecución, si el programador no conoce los costos de estas construcciones "fáciles de usar".

Como resumen, diría que C++ hace que sea más fácil para los programadores sin experiencia escribir código lento (porque no ven ineficiencias directamente en un programa). Pero C++ también permite a los buenos programadores escribir códigos "buenos", correctos y rápidos más rápido que con c, lo que les da más tiempo para pensar acerca de las optimizaciones cuando realmente son necesarias.

P.S .:
Dos cosas que no he mencionado (probablemente entre otros que simplemente olvidó) son C++ capacidad de 's para cálculos complejos en tiempo de compilación (gracias a las plantillas y constexpr) y de c restringen la palabra clave. Esto se debe a que aún no los utilicé en programas de tiempo crítico, por lo que no puedo comentar sobre su utilidad general y el beneficio del rendimiento en el mundo real.

Cuestiones relacionadas