11

Si miro la IL que se creó en Linqpad para los dos fragmentos de código siguientes, me pregunto qué sucede aquí.¿Es el compilador de C# más inteligente que el compilador de VB.NET?

en C#

int i = 42; 

resultados en el siguiente código de IL

IL_0000: ret 

mientras que en VB

Dim i As Integer = 42 

es

IL_0000: ldc.i4.s 2A 
IL_0002: stloc.0 

Aparentemente, el compilador de C# entiende que el valor nunca se usa y, por lo tanto, simplemente no devuelve nada. En VB.NET, el código real se traduce.

¿Eso se debe a diferencias en la optimización del compilador o hay algo más en el trabajo?

Actualización: Solo para aclarar esto, simplemente introduzco esta línea en LinqPad y miro la IL que crea (definitivamente ejecutando el compilador respectivo). No es ningún programa.

+0

Creo que el compilador de C# realiza más optimizaciones, en este momento (esto seguramente cambiará cuando entre Roslyn). Pero en este caso, es una victoria falsa para el compilador de C#, ya que de todos modos será optimizado por el compilador JIT. –

+0

@AakashM: Mientras escribo, esto es todo lo que ingreso en LinqPad. No hay otro código. LinqPad produce IL compilando en segundo plano. – Olaf

+0

¿Compila lo mismo en C# en depuración? Supongo que C# optimiza más cuando está en modo de lanzamiento luego de VB.NET. Esa es una de las razones por las que no se pueden evaluar variables en la versión en C# que no se usan mientras se puede en VB.NET. Yo prefiero este último –

Respuesta

10

Quitando la cuestión LINQPad, me encontré vbc y csc con /optimize+ /debug- sobre estos programas:

Module f 

Public Sub Main() 
    Dim i As Integer = 42 
End Sub 

End Module 

y

public static class f 
{ 

public static void Main() 
{ 
    int i = 42; 
} 

} 

y obtuve estos resultados CIL de ILDASM:

Para el VB:

.method public static void Main() cil managed 
{ 
    .entrypoint 
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = (01 00 00 00) 
    // Code size  4 (0x4) 
    .maxstack 1 
    .locals init (int32 V_0) 
    IL_0000: ldc.i4.s 42 
    IL_0002: stloc.0 
    IL_0003: ret 
} // end of method f::Main 

Para el C#:

.method public hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    // Code size  1 (0x1) 
    .maxstack 8 
    IL_0000: ret 
} // end of method f::Main 

Así, , al menos en este aspecto csc es 'inteligente' que vbc. Pero apuesto a que JITter eliminará cualquier diferencia en el tiempo de ejecución.

edición

he comprobado, y en realidad el código nativo ejecutado es diferente, al menos en mi sistema.Me puse en Console.ReadLine() llamadas en tanto que me dan la oportunidad de adjuntar un depurador, y me dieron estos desmontajes:

Desde la VB:

00000000 sub   rsp,38h 
00000004 mov   dword ptr [rsp+20h],0 
0000000c mov   rax,7FF000434D8h 
00000016 mov   eax,dword ptr [rax] 
00000018 test  eax,eax 
0000001a je   0000000000000021 
0000001c call  FFFFFFFFE45BA230 
00000021 mov   dword ptr [rsp+20h],2Ah 
00000029 call  FFFFFFFFE26ABF20 
0000002e mov   qword ptr [rsp+28h],rax 
00000033 nop 
00000034 jmp   0000000000000036 
00000036 add   rsp,38h 
0000003a ret 

Desde el C#:

00000000 sub   rsp,38h 
00000004 mov   rax,7FF000534D8h 
0000000e mov   eax,dword ptr [rax] 
00000010 test  eax,eax 
00000012 je   0000000000000019 
00000014 call  FFFFFFFFE45AA230 
00000019 call  FFFFFFFFE391BF20 
0000001e mov   qword ptr [rsp+20h],rax 
00000023 nop 
00000024 jmp   0000000000000026 
00000026 add   rsp,38h 
0000002a ret 

Ahora , mi assembley es casi inexistente, pero incluso puedo ver que

mov   dword ptr [rsp+20h],2Ah 

en el from-VB se refiere a un valor constante de hex 2A, que es 42 decimal. Así que ahí lo tienes, hace ejecutar más instrucciones al final.

+2

también tenemos una pila más grande como en 8 (C#) vs 1 – V4Vendetta

1

Creo que en C# case el compilador realiza la parte de asignación de memoria y guarda el valor de int en un paso y en caso de VB la instrucción DIM es el primer paso que asigna memoria y luego el valor se guarda en el segundo paso. DIM es genérico y se usa con todos los tipos de datos, por lo que podría ser algo así como un paso extra en todos los casos. ¿Pensamientos?

Cuestiones relacionadas