CLR y JVM tienen metas y filosofías que difieren más de lo que piensas. En general, la JVM tiene como objetivo optimizar un código más dinámico y de mayor nivel, mientras que CLR le brinda más herramientas de bajo nivel para realizar este tipo de optimizaciones.
Un buen ejemplo es la asignación de la pila. En el CLR tiene una asignación de pila explícita de tipos de valores personalizados. En la JVM, los únicos tipos personalizados son tipos de referencia, pero la JVM puede convertir las asignaciones de pila a las asignaciones de la pila en determinadas circunstancias a través del Análisis de escape.
Otro ejemplo. En Java, los métodos son virtuales por defecto. En C# al menos, no lo son. Es mucho más difícil optimizar las llamadas a métodos virtuales porque el código que se ejecuta en un sitio de llamadas determinado no se puede determinar estáticamente.
Debajo del capó, sus sistemas de ejecución son bastante diferentes. La mayoría de las JVM (en particular, Hotspot) comienzan con un intérprete de bytecode y solo partes de compilación JIT del código que se ejecutan en gran medida, p. bucles apretados. También pueden volver a compilar estos datos una y otra vez utilizando las estadísticas de ejecución recopiladas de las ejecuciones anteriores para generar optimizaciones. Esto permite que se apliquen más esfuerzos de optimización a las partes del programa que más lo necesitan. Esto se llama optimización adaptativa.
El CLR compila todo por adelantado solo una vez. Hace menos optimización, ya que tiene más código para compilar y, por lo tanto, tiene que ser rápido y porque no tiene ninguna estadística de las rutas de ejecución reales tomadas para alimentar sus optimizaciones. Este enfoque tiene la gran ventaja de permitirle almacenar en caché los resultados de compilación en todos los procesos, lo que hace CLR pero JVM no.
Un gran porcentaje del código JVM de Hotspot está dedicado a estas optimizaciones adaptativas y es lo que coloca a Java en el mismo estadio de rendimiento como código nativo para el cálculo más general a principios de la década de 2000. También son lo que hace que la JVM sea un objetivo decente para los lenguajes dinámicos. Estoy excluyendo aquí los desarrollos más recientes de Dynamic Languages Runtime e invochedynamic ya que no sé lo suficiente sobre el DLR.
Sugiero comenzar una nueva pregunta con el tema que más le interese, haciendo referencia a esta pregunta. De esta manera puede cubrir cada tema más profundamente, si hay expertos alrededor de –