C++/CLI y C#: Asombrosas diferencias en el optimizador de código (IV)
Publicado
7/8/2007 18:15
por
Rafael Ontivero
Por fin algo de coherencia en el tema. Vicente, en la segunda parte de esta serie, da en el clavo, pero el jitter sigue siendo bastante malo. ¿Por qué no hace el compilador de C# lo mismo que el de C++/CLI y deja más suelto el jitter. Sigo viéndolo un error bastante garrafal.
Vamos a ello.
Modifiquemos el programa y dejémoslo así:
using System;
using System.Collections.Generic;
using System.Text;
namespace TestCS1
{ class Program
{ static void CallPrint()
{ //Console.WriteLine("CallPrint"); }
static void DoWork()
{ for (int i = 0; i < 1000; i++)
CallPrint();
}
static void Main(string[] args)
{ for(uint i=0;i<UInt32.MaxValue;i++)
//while(true)
DoWork();
Console.WriteLine("Hello World"); }
}
}
El cambio consiste en cambiar el bucle for dentro de main() por un bucle prácticamente infinito. Como nos comenta Vicente, si queremos ver al jitter en todo su esplendor, debemos o bien utilizar el depurador de línea de comando o bien anexar el Visual Studio a un proceso ya en ejecución (esto no lo sabía, yo pensaba que ejecutando bajo el depurador entraba todo en acción).
Compilamos el programa y lo lanzamos sin el depurador, es decir, pulsamos May-Alt-F5 o seleccionamos la opción correspondiente desde el menú Debug.
Una vez que hayamos lanzado el programa, nos vamos al menú Debug y seleccionamos "Attach to process", buscamos TestCS3 en la lista de procesos y una vez hecho eso, pausamos el programa anexado.
Después, vemos la ventana de "Disassembly" (quizás tengamos que ejecutar unos cuantos pasos o "Step out" para volver a main():
Vemos algo menos de código que en la versión sin jittear (permítaseme la expresión), pero seguimos teniendo la llamada a DoWork() que, aunque ya no llama al método vacío, sigue repitiendo un bucle bastante absurdo y sin sentido:
Supongo que el jitter habrá tenido tiempo de optimizar el código en las miles de pasadas que el programa haya podido realizar entre que lo lanzamos y lo anexamos al depurador (de hecho ya no vemos esas extrañas llamadas dentro del código).
Resumiendo: que sigue siendo mejor optimizar en la compilación (aunque evidentemente, también es bueno tener un jitter) que en tiempo de ejecución. De hecho, el código realizado en C++/CLI sigue siendo sensiblemente más rápido sin la pasada del jitter que el de C# con varias miles de vueltas…
Pero ahora surge otro problema muy serio: si el código en Release no es el mismo que cuando la máquina se ejecuta sola, seguro que habrá muchas diferencias entre el código que se ejcuta dentro del Visual Studio y el que lo hace fuera de él, es decir, no estamos completamente seguros de que nuestro código vaya a funcionar bien en otras máquinas (y es ahora cuando yo me explico los problemas que he tenido y sigo teniendo con el código en producción, que a veces no funciona como debiera…).