¿Podemos hacer declaraciones generales sobre el rendimiento del código interpretado frente al código compilado?

60

Estoy comparando dos tecnologías para llegar a una recomendación para la cual una empresa debería usar una. El código de la tecnología A se interpreta mientras que el código de la tecnología B se compila al código de máquina. En mi comparación, declaro que la tecnología B en general tendría un mejor rendimiento, ya que no tiene la sobrecarga adicional del proceso de interpretación. También declaro que, dado que un programa podría escribirse de muchas maneras, todavía es posible que un programa escrito en tecnología A pueda superar a uno escrito en tecnología B.

Cuando presenté este informe para su revisión, el revisor declaró que no ofrecí una razón clara por la que, en general, la sobrecarga del proceso de interpretación fuera lo suficientemente grande como para que podamos concluir que el rendimiento de la tecnología B sería mejor.

Entonces, mi pregunta es: ¿podemos alguna vez decir algo sobre el rendimiento de las tecnologías compiladas / interpretadas? Si podemos decir que compilado es generalmente más rápido de lo que se interpreta, ¿cómo podría convencer al revisor de mi punto?

    
pregunta EpicSam 10.01.2017 - 13:34

14 respuestas

111

No.

En general, el rendimiento de una implementación de lenguaje depende principalmente de la cantidad de dinero, recursos, mano de obra, investigación, ingeniería y desarrollo que se gasta en ella.

Y específicamente, el rendimiento de un programa en particular depende principalmente de la cantidad de pensamiento puesto en sus algoritmos.

Hay algunos muy intérpretes rápidos y algunos compiladores que generan el código muy lento .

Por ejemplo, una de las razones por las que Forth sigue siendo popular es que, en muchos casos, un programa Forth interpretado es más rápido que el programa C compilado equivalente, mientras que, al mismo tiempo, el programa de usuario escrito en Forth plus el intérprete Forth escrito en C es más pequeño que el programa de usuario escrito en C.

    
respondido por el Jörg W Mittag 10.01.2017 - 14:07
81

Las generalizaciones y los escenarios específicos son literalmente opuestos.

Pareces contradecirte a ti mismo. Por un lado, desea hacer una declaración general sobre los idiomas interpretados frente a los compilados. Pero, por otro lado, desea aplicar esa declaración general a un escenario concreto que involucre la Tecnología A y la Tecnología B.

Una vez que apliques algo a un escenario concreto, ya no está generalizado . Entonces, incluso si puede afirmar que los lenguajes interpretados son más lentos en general , todavía no está expresando su punto. A tu crítico no le importan las generalizaciones. Estás haciendo un análisis de dos tecnologías muy específicas. Eso es literalmente lo contrario de generalizar.

    
respondido por el loneboat 10.01.2017 - 20:44
37

Como regla general, un programa interpretado es aproximadamente 2x-10x más lento que escribir el programa en el idioma principal del intérprete, mientras que los intérpretes para los idiomas más dinámicos son más lentos. Esto se debe a que el programa interpretado tiene que hacer todo el trabajo real, pero además tiene la sobrecarga de interpretación.

Dependiendo de la estructura del intérprete, puede haber diferencias muy significativas. Hay dos escuelas contradictorias de diseño de intérpretes: una dice que los códigos de operación deben ser lo más pequeños posible para que puedan optimizarse más fácilmente, la otra dice que los códigos de operación deben ser lo más grandes posible para que podamos trabajar más dentro del intérprete. Cuando la estructura de su programa coincide con la filosofía del intérprete, los gastos generales se vuelven insignificantes.

Por ejemplo, Perl es un lenguaje interpretado orientado a la manipulación del texto. Un programa idiomático de Perl que realiza la manipulación de texto no será mucho más lento que un programa en C, e incluso puede superar al programa en C en algunos casos (es posible porque Perl usa una representación de cadena diferente y tiene varias optimizaciones relacionadas con IO y texto incorporadas). Sin embargo, hacer cálculos numéricos en Perl va a ser insoportablemente lento. Un incremento ++x es una sola instrucción de ensamblaje, pero implica múltiples recorridos de punteros y ramas para el intérprete de Perl. Recientemente porté una secuencia de comandos Perl vinculada a la CPU a C ++ y obtuve una aceleración de 7x-20x, según el nivel de optimización del compilador.

Hablar sobre optimizaciones es importante aquí, ya que un intérprete optimizado y pulido puede superar razonablemente a un compilador ingenuo que no optimiza. Dado que crear un compilador de optimización es difícil y requiere mucho esfuerzo, es poco probable que su "tecnología B" tenga este nivel de madurez.

(Nota: el Idioma del equipo El sitio Benchmarks Game tiene una estructura confusa, pero una vez que alcanza la tabla de tiempos para un problema, notará que el rendimiento de varios idiomas está por todos lados, a menudo, no hay un límite claro de rendimiento entre los compilados y soluciones interpretadas. La parte más importante del sitio no son los resultados de los puntos de referencia, sino las discusiones sobre qué tan difíciles son los puntos de referencia significativos.)

Al elegir una tecnología, el rendimiento del tiempo de ejecución de un idioma en sí mismo es completamente irrelevante. Es más probable que sea importante que la tecnología cumpla con algunas restricciones de referencia (nuestro presupuesto es de $ x, debemos ser capaces de entregar antes de yyyy-mm-dd, debemos cumplir varios requisitos no funcionales), y de que tenga un menor costo total de propiedad (factorización en la productividad del desarrollador, costos de hardware, costos de oportunidad de negocio, riesgo de errores y restricciones inesperadas en la tecnología, costos de mantenimiento, costos de capacitación y contratación, ...). P.ej. en una industria donde el tiempo de comercialización es el factor más importante, la tecnología con la mejor productividad para desarrolladores sería la mejor opción. Para una organización grande, la capacidad de mantenimiento y los costos a largo plazo pueden ser más interesantes.

    
respondido por el amon 10.01.2017 - 14:52
18

Absolutamente puede decir algo sobre el rendimiento de las tecnologías compiladas / interpretadas. Pero primero, debes definir "performance". Si está creando un sistema integrado computacionalmente simple, entonces el "rendimiento" probablemente se incline hacia el lado de la utilización de la memoria. Mientras que un sistema computacionalmente complejo que opera con grandes conjuntos de datos, se encontrará definiendo "rendimiento" en el número de cómputos por unidad de tiempo, ya que la sobrecarga de memoria de JVM o .NET sería despreciable.

Una vez que decida qué es el "rendimiento", entonces puede decir algo como "tendremos 50 mil millones de objetos en memoria en un momento dado y la tecnología interpretada agrega 8 bytes adicionales a cada objeto para la administración interna, lo que equivale a una Sobrecarga de memoria de 400GB en comparación con techB que no agrega estos datos "

    
respondido por el jhbh 10.01.2017 - 14:02
12

Esta es una pregunta técnica y ya tiene muchas respuestas técnicas, pero me gustaría señalar un aspecto ligeramente diferente de su situación: el hecho de que no puede basar una decisión como "tecnología A o tecnología B "puramente por razones técnicas y / o de rendimiento.

Los aspectos técnicos de algo como esto son solo una pequeña parte de la decisión entre A y B. Hay docenas de otros factores a tener en cuenta:

  • ¿Implica algún costo de licencia? Por ejemplo: tiene que pagar (una cantidad sustancial) para usar un grupo de máquinas de SQL Server en lugar de usar un grupo de máquinas de PostgreSQL.
  • ¿Tengo empleados que estén familiarizados con esa tecnología (pila) y su ecosistema? En caso afirmativo, ¿están disponibles? Si no, ¿puedo contratar algunos? ¿Cuánto me costará? ¿O entreno a los existentes? ¿Cuánto me costará eso?
  • ¿Qué quiere el cliente? Esto puede ser un problema muchas veces.
  • ¿La tecnología que recomiendo está lista para el uso en producción? ¿O es solo una exageración actual que quizás desaparezca? (por ejemplo, piense en Node.js cuando salió)
  • ¿La tecnología que recomiendo encaja bien con la arquitectura existente o con la arquitectura que tenía en mente? ¿O tengo que gastar mucho dinero al hacer que funcionen juntos a la perfección?
  • y muchos más aspectos que dependen de su situación específica.

Como puede ver, hay TONELADAS de cosas a considerar al tomar una decisión de este tipo.

Sé que esto no responde específicamente a su pregunta, pero creo que brinda una visión más general de su situación y los detalles de esa decisión.

    
respondido por el Radu Murzea 11.01.2017 - 13:16
10

Evaluación parcial es un marco conceptual relevante para relacionar intérpretes y compiladores.

  

¿Podemos hacer declaraciones generales sobre el rendimiento del código interpretado frente al código compilado?

Los lenguajes de programación son especificaciones (escritos en algún informe, como R5RS o n1570 ). Son software no , por lo que ni siquiera tiene sentido hablar de rendimiento . Pero algunos lenguajes de programación pueden tener varias implementaciones, incluyendo intérpretes y compiladores .

Incluso en lenguajes compilados tradicionalmente (es decir, lenguajes cuyas implementaciones a menudo son compiladores) como C, algunas partes se interpretan a menudo. Por ejemplo, la cadena de control de formato de printf (definida en el estándar C) es a menudo "interpretado" (por la biblioteca estándar de C , que tiene una función printf usando técnicas de argumentos variables) pero algunos compiladores (incluyendo GCC ) son capaces de limitar casos específicos: para optimizarlo y "compilarlo" en llamadas de nivel inferior.

Y algunas implementaciones, incluso dentro de "intérpretes", están utilizando las técnicas de compilación JIT (así que genere la máquina código en runtime ). Un buen ejemplo es luajit . Otras implementaciones (por ejemplo, Python, Ocaml, Java, Parrot, Lua) están traduciendo el código fuente a un bytecode que luego se interpreta. .

SBCL es un "compilador" de Common Lisp que traduce dinámicamente cada REPL (y las llamadas a eval etc ...) en el código de la máquina. Así que sientes que es un intérprete. La mayoría de las implementaciones de JavaScript en los navegadores (por ejemplo, v8 ) utilizan técnicas de compilación JIT.

En otras palabras, la diferencia entre los intérpretes y los compiladores es muy borrosa (en realidad hay una continuidad entre ambos), y prácticamente hablando, la mayoría de las implementaciones del lenguaje de programación tiene a menudo tanto un intérprete como un compilador ( al menos al código de byte) faceta.

Una implementación puede ser rápida o lenta independientemente del uso de la mayoría de las técnicas de tipo "compilador" o "intérprete".

Algunos rasgos del lenguaje favorecen un enfoque de interpretación (y solo se pueden compilar de manera eficiente a través del análisis de todo el programa ).

Para algunos tipos de problemas, vale la pena diseñar el software con algunos metaprogramming . Da importantes aceleraciones. Podría imaginar que, dada una entrada específica, su programa dinámicamente genera un código especializado para procesarlo. Esto es incluso posible con C o C ++ (ya sea usando alguna biblioteca JIT o generando algún código C, compilándolo como un complemento que se carga dinámicamente).

Vea también esta pregunta relacionada sobre Python, y que

    
respondido por el Basile Starynkevitch 11.01.2017 - 09:31
7

Para código como A = A + B , que puede compilar hasta una o dos instrucciones de máquina, cada una de ellas con un cierto número de ciclos. Ningún intérprete puede hacer lo mismo en ese número de ciclos por una simple razón.

El intérprete también ejecuta un conjunto de instrucciones propio (llámelos códigos de bytes, códigos p, lenguaje intermedio, lo que sea). Cada vez que ve un código de bytes como AGREGAR, debe buscarlo de alguna manera y derivarse al código que hace la adición.

La siguiente vez que la ve, tiene que repetir esa búsqueda, a menos que tenga una forma de recordar la búsqueda anterior. Si tiene una manera de recordar la búsqueda anterior, ya no es lo que llamamos un "intérprete", sino un compilador justo a tiempo, o JITter.

Por otro lado ...

Para códigos como callSomeFunction( ... some args ...) , ¿cuántos ciclos se gastan entre ingresar ese código y dejarlo? Todo depende de lo que ocurra dentro de callSomeFunction . Podrían ser unos pocos, y podrían ser billones, incluso si callSomeFunction está compilado. Si es mucho, no tiene sentido debatir el costo de interpretación de esa línea de código, el dinero está en otra parte.

Recuerde que los idiomas interpretados tienen un valor propio, como, por ejemplo, no es necesario compilarlos. (La "compilación" de la sintaxis de la superficie a los códigos de bytes toma un tiempo trivial. Tome R o MATLAB, por ejemplo).

También, se necesita flexibilidad para niveles inteligentes de programación. En Society of Mind de Minsky, Capítulo 6.4 B -Frenos, hay programas A que tratan con el mundo, y programas B que tratan con los programas A, y puede haber niveles adicionales. Los programas que escriben y administran otros programas se pueden hacer más fácilmente en sistemas interpretativos.

En Lisp, puedes escribir (+ A B) para agregar A y B, pero una vez que está escrito solo tienes la opción de ejecutarlo o no. También puede escribir (eval (list '+ 'A 'B)) que construye el programa y luego lo ejecuta. Podría construir algo diferente.

El tema del programa es otro programa . Esto es más fácil de escribir en un lenguaje interpretado (aunque, como señala Jörg, las versiones más recientes de Lisp, mientras que tienen eval , compila sobre la marcha, por lo que no tienen la penalización de velocidad de la interpretación). / p>     

respondido por el Mike Dunlavey 10.01.2017 - 14:38
5

Es un tipo de, depende de, pero como regla general, el entorno compilado, ya sea a través de JIT o estáticamente compilado, será más rápido para muchas tareas de uso intensivo de cómputo, suponiendo que sea un lenguaje sencillo.

Parte de la razón es que los lenguajes interpretados necesitan tener un bucle de bucle de intérprete que lea una instrucción, seleccione la acción apropiada para realizarla y la ejecute. En el mejor de los casos, como interpretar Python o Java bytecode (como old JVM), tiene una sobrecarga de pocas instrucciones y causó estragos en el predictor de la rama, sin la última puede esperar grandes penalizaciones debido a predicciones erróneas. Incluso un JIT muy tonto debería acelerar esto significativamente.

Dicho esto, el lenguaje interpretado puede hacer trampa. Por ejemplo, Matlab ha optimizado las rutinas para la multiplicación de matrices y con pocos cambios puede ejecutar el código en la GPU (exención de responsabilidad: trabajo para nVidia: cualquier opinión expresada aquí es mía y no representa la opinión de mi empleador). De esa manera, puede escribir código de nivel alto breve y potente sin preocuparse por los detalles: alguien se ocupó de ello y dedicó tiempo y recursos a la optimización en lenguaje de bajo nivel. No hay nada heredado al respecto y no impide, por ejemplo, aplicar Matlab al JIT del código, pero a menudo no hay razón, ya que la sobrecarga de llamadas a la rutina de alto nivel es mínima en comparación con el tiempo empleado en los de bajo nivel.

TL; DR: los programas compilados tienen enormes beneficios de rendimiento sobre los interpretados (para la comparación manzanas con manzanas, vea PyPy Speed ). Sin embargo, la velocidad del ejecutable es solo una parte del problema y puede que no contribuya mucho a la velocidad general (si la mayor parte del tiempo se dedica a las bibliotecas). También importa la implementación.

    
respondido por el Maciej Piechotka 11.01.2017 - 09:09
5

Su suposición está bien fundada, aunque es una suposición.

No voy a repasar las razones por las que el código compilado debería ser más rápido que el código interpretado: si sabes cómo funcionan las computadoras, eso será obvio. La diferencia puede ser de órdenes de magnitud para ciertos tipos de problemas. Si su crítico disputa seriamente ese caso general, no saben de qué están hablando.

Aunque pueden tener un punto es si la diferencia es significativa en el tipo de aplicación que está desarrollando. Si se trata principalmente de E / S o, en su mayoría, de bibliotecas compiladas y no tiene muchos cálculos, la sobrecarga del proceso de interpretación puede ser insignificante.

Pero el punto de mi publicación es este: como un I.T. experto, a menudo se lo llamará para tomar decisiones rápidas basadas en un conocimiento general de cómo deberían funcionar las cosas. Hacer una prueba específica podría ofrecerte una respuesta más precisa, pero te costará mucho más y no te llevará allí primero.

Pero de vez en cuando te atrapan. Me ha pasado Usted hace una buena suposición y luego descubre que no tuvo en cuenta la estupidez del mundo.

Pero no puedo explicar tan bien como mi dibujo animado favorito de Dilbert de todos los tiempos. Nada muestra mejor que esto los peligros de ser un asno inteligente.

TL; DR: debes tener razón, pero revisa el mundo real por si acaso.

    
respondido por el rghome 13.01.2017 - 09:53
3

A menos que use algo un tanto exótico, su problema no será sobre el rendimiento de un lenguaje interpretado A y un lenguaje compilado B.

Porque si usted / su equipo sabe A y no B y, por lo tanto, escribe mejor el código en A que en B, puede tener un desempeño mucho mejor en A que en B. Si tiene personas con experiencia en un idioma y el idioma / bibliotecas Puede hacer el trabajo que necesita, seguirlo.

Aquí hay un enlace sobre expresiones regulares en varios idiomas; verá que las expresiones regulares se implementan mejor en algún lenguaje, incluso si están compiladas o no: enlace

    
respondido por el Walfrat 10.01.2017 - 14:04
1

Creo que no es una buena idea hablar sobre el rendimiento de dos tecnologías solo por el hecho de que una se compila y la otra se interpreta. Como se indica en otras respuestas, puede depender del área de la aplicación (algunos idiomas pueden optimizarse para realizar algunas operaciones muy rápidamente y hacer otras cosas más lentamente), así como en la experiencia de las personas que están a punto de usar esa tecnología. p>

No creo que sea razonable esperar que obtengas un aumento en el rendimiento si tomas unos excelentes codificadores de lenguaje interpretados y les das una tecnología con la que no están familiarizados, tal vez en teoría esto último puede dar como resultado un mejor rendimiento, pero en realidad, sin las habilidades y experiencia necesarias, no utilizará todas las oportunidades de optimización.

Por parte de uno de los conocidos empleados de la compañía de Silicon Valley, también escuché que prefieren el lenguaje que es más fácil de usar, ya que es más costoso y problemático pagar a algunos desarrolladores expertos para mantener un código complicado pero altamente optimizado. que solo comprar una plataforma para lidiar con una implementación menos eficiente, por lo que también debe considerarse al elegir la tecnología.

    
respondido por el KjMag 11.01.2017 - 11:11
0

Una vez tuve que hacer una declaración similar para justificar una gran decisión.

Primero, es posible que no quieran creerle a un ingeniero humilde, así que encontré algunas pruebas comparativas comparables y las cité. Hay muchos acerca de ellos, de personas como Microsoft o universidades reconocidas. Y dirán cosas como: El método A es entre 3 y 10 veces más rápido que el método B, dependiendo de las variables X e Y.

En segundo lugar, es posible que desee ejecutar un punto de referencia propio, tal vez utilizando una parte representativa del código en cuestión, o algo similar que ya tenga. Ejecutarlo 1000 veces durante la noche, así que realmente hay una diferencia mensurable.

En este punto, la diferencia (o la falta de ella) entre A y B debería ser tan clara que solo tiene que presentarla. Entonces formatee los resultados claramente, con diagramas si es posible, estableciendo todos los supuestos y definiendo todos los datos utilizados.

    
respondido por el RedSonja 12.01.2017 - 15:01
0

Yo diría que cualquier lenguaje dinámico tiene una ventaja sobre los compilados estáticamente: "Optimizaciones de tiempo de ejecución"

Esa es una de las razones por las que Java puede ser más rápido que C ++

Sí, cargar un idioma escrito dinámicamente siempre tendrá el costo de traducción y estará en desventaja. Pero una vez que se está ejecutando, el intérprete puede perfilar y mejorar las rutas de código frecuentes con información de tiempo de ejecución que los lenguajes estáticos nunca tendrán

NOTA: Bueno, Java es un lenguaje interpretado, no dinámico. Pero es un gran ejemplo de lo que puede acelerar con información de tiempo de ejecución

    
respondido por el SystematicFrank 14.01.2017 - 09:26
-3
  

... También declaro que dado que un programa puede escribirse de muchas maneras, es   Todavía es posible que un programa escrito en tecnología A pueda superar a uno   escrito en tecnología B.

     

Cuando envié este informe para su revisión, el revisor declaró que   No ofreció ninguna razón clara por la que, en general, la sobrecarga de la   proceso de interpretación sería lo suficientemente grande como para que pudiéramos concluir   El rendimiento de esa tecnología B sería mejor. ...

Este sería mi enfoque:

En general, los intérpretes se compilan, por lo que cada tecnología interpretada no es más que una tecnología compilada si se la observa en un nivel bajo. Por lo tanto, las tecnologías compiladas son más y con más posibilidades, nunca podrá empeorar si es inteligente (lo que en general es). Depende de cuánta información haya disponible en tiempo de compilación y cuánta información esté disponible solo en tiempo de ejecución y de cuán buenos sean los compiladores e intérpretes, pero en teoría siempre debería ser posible igualar al menos el rendimiento de cualquier intérprete con un compilador adecuado. solo porque los intérpretes son fabricados por compiladores. Que sea posible, no significa que sea el caso de tus técnicos A y B, sin embargo.

En la práctica, simplemente informe al revisor acerca de todos los puntos de referencia disponibles donde se comparan los sistemas compilados e interpretados. Luego, pídale que le sugiera un intérprete que supere su algoritmo específico de código ensamblado optimizado.

Tal vez debería agregarse que cualquier declaración general no ayuda en absoluto cuando se comparan dos técnicos específicos A y B. En este caso, la elección de A y B importa mucho, mucho más, que si se interpretan o compilan.

    
respondido por el Trilarion 12.01.2017 - 12:03

Lea otras preguntas en las etiquetas