2012-08-09 15 views
6

Los intérpretes hacen mucho trabajo extra, por lo que es comprensible que terminen significativamente más lento que el código de máquina nativo. Pero los lenguajes como C# o Java tienen compiladores JIT, que supuestamente se compilan con el código máquina nativo de la plataforma.¿Por qué los lenguajes JIT-ed son aún más lentos y menos eficientes en la memoria que C/C++ nativo?

Y, sin embargo, de acuerdo con benchmarks que parece lo suficientemente legítimo, en la mayoría de los casos son todavía 2-4 veces más lento que C/C++? Por supuesto, me refiero a un código C/C++ igualmente optimizado. Soy muy consciente de los beneficios de la optimización de la compilación de JIT y su capacidad para producir código que es más rápido que C + C++ poco optimizado.

Y después de todo ese ruido acerca de cuán buena es la asignación de memoria de Java, ¿por qué tal horrendous uso de memoria? De 2x a 50x, en promedio se usa alrededor de 30x veces más de memoria en ese conjunto de referencia particular, lo cual no es nada estornudar en ...

NOTA que no quiero iniciar una GUERRA, estoy preguntando por la detalles técnicos que definen esas cifras de rendimiento y eficiencia.

+1

.let la guerra ... COMENZAR! –

+0

[¿Por qué java tiene la reputación de ser lento?] (Http://stackoverflow.com/questions/2163411/why-did-java-have-the-reputation-of-being-slow) – assylias

+0

Si bien ambos compiladores JIT y Los compiladores fuera de línea tienen que equilibrar el tiempo de compilación con la velocidad de ejecución, los compiladores fuera de línea pueden colocar la balanza más en la velocidad de ejecución. – harold

Respuesta

7

Algunas razones para las diferencias;

  • Los compiladores JIT compilan en su mayoría rápidamente y saltean algunas optimizaciones que tardan más en encontrar.

  • VM a menudo imponen la seguridad y esto ralentiza la ejecución. P.ej. acceso a la matriz siempre se Bounds registró .Net menos garantizada dentro del rango correcto

  • Usando SSE (ideal para el rendimiento si es aplicable) es fácil de C++ y dura de VM actual de

  • rendimiento se vuelve más prioridad en C++ sobre otros aspectos cuando se los compara con VM

  • Las máquinas virtuales a menudo guardan la memoria no utilizada un tiempo antes de volver al sistema operativo que parece 'usar' más memoria.

  • objetos de Algunos VM maquillaje de los tipos de valor como int/ulong .. memoria de objeto añadiendo sobrecarga

  • Algunas estructuras de datos alineación automática de VM mucho desperdicio de memoria (para mejoras de rendimiento)

  • Algunos VM implemente un valor booleano como int (4 bytes), mostrando poco enfoque en la conservación de la memoria.

+1

+1 Esa es una buena respuesta para la parte de velocidad, ¿te importa compartir algo del lado de la memoria? Sé que tener un GC y crear objetos para todo tiene una carga no trivial. * Cada objeto * tiene * al menos * una palabra de sobrecarga (metadatos GC), más frecuentemente dos. – delnan

0

Para la memoria puede hacer referencia a here

uso de memoria Java es mucho más pesado que el uso de la memoria C++ 's porque:

  • Hay un overhead de 8 bytes para cada objeto [57] y 12 bytes para cada matriz [58] en Java (32 bits, el doble en Java de 64 bits). Si el tamaño de un objeto no es un múltiplo de 8 bytes, se redondea al siguiente múltiplo de 8. Esto significa que un objeto que contiene un solo campo de bytes ocupa 16 bytes y requiere una referencia de 4 bytes. Tenga en cuenta que C++ también asigna un puntero (generalmente 4 u 8 bytes) para cada objeto que declara funciones virtuales. [59]
  • Las partes de la Biblioteca Java deben cargarse antes de la ejecución del programa (al menos las clases que el programa usa "debajo del capó").[60] Esto lleva a una sobrecarga de memoria significativa para aplicaciones pequeñas [cita requerida].
  • Tanto las recompilaciones nativas como binarias de Java estarán normalmente en la memoria.
  • La máquina virtual en sí misma consume una gran cantidad de memoria.
  • En Java, se crea un objeto compuesto (clase A que usa instancias de B y C) utilizando referencias a instancias asignadas de B y C. En C++, la memoria y el costo de rendimiento de estos tipos de referencias se pueden evitar cuando la instancia de B y/o C existe dentro de A.
  • La falta de aritmética de direcciones hace imposible la creación de contenedores de memoria eficiente, tales como estructuras estrechamente espaciadas y listas vinculadas XOR, imposibles.

En la mayoría de los casos, una aplicación C++ consumirá menos memoria que la aplicación Java equivalente debido a la gran sobrecarga de la máquina virtual de Java, carga de clases y cambio de tamaño automático de la memoria. Para las aplicaciones en las que la memoria es un factor crítico para elegir entre idiomas y entornos de tiempo de ejecución, se requiere un análisis de costo/beneficio.

También se debe tener en cuenta que un programa que utiliza un recolector de basura puede necesitar tanto como cinco veces la memoria de un programa que usa administración de memoria explícita para alcanzar el mismo rendimiento. [61]

Cuestiones relacionadas