Pregunta

Hace poco leí una discusión acerca de si lenguajes administrados son más lentos (o más rápido) que los idiomas nativos (en concreto C # y C ++). A una persona que contribuyó a la discusión, dijo que los compiladores JIT de lenguajes administrados serían capaces de realizar optimizaciones sobre las referencias que simplemente no es posible en los idiomas que utilizan punteros.

Lo que me gustaría saber es qué tipo de optimizaciones que son posibles en las referencias y no en punteros?

Tenga en cuenta que la discusión era sobre la velocidad de ejecución, no uso de la memoria.

¿Fue útil?

Solución

Hay algunos beneficios de JIT compilación mencionado en Wikipedia:

  

código JIT en general, ofrece un rendimiento mucho mejor que los intérpretes. Además, puede en algunos o en muchos casos ofrecen un mejor rendimiento que la compilación estática, ya que muchas optimizaciones sólo son factibles en tiempo de ejecución:

     
      
  1. La compilación se puede optimizar para la CPU objetivo y el modelo del sistema operativo en el que la aplicación se ejecuta. Por ejemplo JIT puede elegir instrucciones de la CPU SSE2 cuando detecta que la CPU compatible con ellas. Con un compilador estático hay que escribir dos versiones del código, posiblemente usando ensamblador en línea.
  2.   
  3. El sistema es capaz de recoger estadísticas acerca de cómo el programa se está ejecutando en el entorno donde se encuentra, y se puede reorganizar y volver a compilar para un rendimiento óptimo. Sin embargo, algunos compiladores estáticos también pueden tomar información de perfil como entrada.
  4.   
  5. el sistema puede hacer optimizaciones de código globales (por ejemplo, procesos en línea de funciones de la biblioteca) sin perder las ventajas de la vinculación dinámica y sin los gastos inherentes a los compiladores estáticos y enlazadores. En concreto, al hacer sustituciones en línea a nivel mundial, un compilador estático debe insertar controles en tiempo de ejecución y asegurar que se produciría una llamada virtual si la clase real del objeto reemplaza el método inline.
  6.   
  7. A pesar de que esto es posible con lenguajes compilados estáticamente recogida de basura, un sistema de código de bytes puede reorganizar más fácilmente la memoria caché para una mejor utilización.
  8.   

No puedo pensar en algo relacionado directamente con el uso de referencias en lugar de punteros.

Otros consejos

En C ++ hay dos ventajas de referencias relacionadas con aspectos de optimización:

  1. Una referencia es constante (se refiere a la misma variable para toda su vida útil)

    Debido a esto, es más fácil para el compilador para inferir qué nombres se refieren a las mismas variables subyacentes - creando así oportunidades de optimización. No hay garantía de que el compilador hará mejor con referencias, pero podría ...

  2. A de referencia se asume para referirse a algo (no hay referencia null)

    Una referencia que "se refiere a nada" (equivalente al puntero NULL) puede ser creado, pero esto no es tan fácil como crear un puntero NULL. Debido a esto el cheque de la referencia para NULL se puede omitir.

Sin embargo, ninguna de estas ventajas se traspasan directamente a lenguajes administrados, por lo que no veo la relevancia de que en el contexto de su tema de discusión.

En el habla general, las referencias hacen que sea posible se refieren al mismo objeto desde diferentes lugares.

A 'puntero' es el nombre de un mecanismo de aplicación de referencias. C ++, Pascal, C ... tiene punteros, C ++ ofrece otro mecanismo (con poco otros casos de uso) llamado 'de referencia', pero estos son esencialmente todas las implementaciones del concepto general de referencia.

Así que no hay razón por la que las referencias son, por definición, más rápido / más lento que los punteros.

La verdadera diferencia está en el uso de un JIT o un compilador clásico 'en la delantera': el JIT puede tomar en cuenta los datos que no están disponibles para el compilador frontal hacia arriba. No tiene nada que ver con la aplicación del concepto de 'referencia'.

Otras respuestas son correctas.

Sólo añadiría que cualquier optimización no hará un grito de la diferencia a menos que sea en el código donde el contador de programa en realidad pasa mucho tiempo, al igual que en los bucles que no contienen las llamadas de función (por ejemplo, la comparación de cadenas).

una referencia de objeto en un marco administrado es muy diferente de una referencia aprobada en C ++. Para entender lo que los hace especiales, imagínese cómo se manejaría el siguiente escenario, a pie de máquina, sin referencias a objetos recolección de basura: Método "Foo" devuelve una cadena, que se almacena en varias colecciones y se pasa a diferentes piezas de código. Una vez que nada necesita la cadena más, debería ser posible para recuperar toda la memoria utilizada en el almacenamiento, pero no está claro qué parte del código será el último en utilizar la cadena.

En un sistema no-GC, cada colección o bien tiene que tener su propia copia de la cadena, o de lo contrario tiene que sostener algo que contiene un puntero a un objeto compartido que contiene los caracteres de la cadena. En esta última situación, el objeto compartido necesita saber de alguna manera cuando el último puntero a que sea eliminado. Hay una variedad de maneras en que esto puede ser manejado, sino un aspecto esencial común de todos ellos es que los objetos compartidos necesitan ser notificado cuando punteros a ellos se copian o destruidos. Dicha notificación requiere trabajo.

En un sistema de GC por el contrario, los programas están decoradas con metadatos que decir que registra o partes de un marco de pila serán utilizados en un momento dado para contener referencias a objetos arraigados. Cuando se produce un ciclo de recogida de basura, el recolector de basura tendrá que analizar estos datos, identificar y preservar todos los objetos activos y bombardear todo lo demás. El resto del tiempo, sin embargo, el procesador puede copiar, reemplazar, reproducción aleatoria, o destruir las referencias en cualquier patrón o secuencia que le gusta, sin tener que notificar a cualquiera de los objetos involucrados. Tenga en cuenta que cuando se utiliza notificaciones puntero de uso en un sistema multiprocesador, si los diferentes hilos pueden copiar o destruir las referencias al mismo objeto, se requiere código de sincronización para efectuar la notificación necesaria flujos seguros. Por el contrario, en un sistema de GC, cada procesador puede cambiar las variables de referencia en cualquier momento sin tener que sincronizar sus acciones con cualquier otro procesador.

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