2009-06-18 10 views

Respuesta

13

El compilador todavía usa la instrucción newarr IL, por lo que el CLR aún inicializará la matriz.

La inicialización de la colección es solo compilador magic: el CLR no sabe nada al respecto, por lo que aún supondrá que tiene que hacer una limpieza de cordura.

Sin embargo, esto debería ser muy, muy rápido; solo borra la memoria. Dudo que sea una sobrecarga significativa en muchas situaciones.

+0

Interesante. Me pregunto si este enfoque de "borrado de memoria" para la inicialización de la matriz es una de las razones por las cuales las estructuras no admiten constructores predeterminados explícitos o inicializadores de miembros. Esto complicaría la inicialización de la matriz. – LBushkin

+1

Sí, eso es mucho. De hecho, las estructuras en IL * do * admiten constructores sin parámetros, pero solo se invocarán en determinadas situaciones. –

+0

Consulte http://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types-and-parameterless-constructors.aspx para obtener más información. –

10

prueba rápida:

 string[] arr1 = 
     { 
      "A","B","C","D" 
     }; 
     arr1.GetHashCode(); 

     string[] arr2 = new string[4]; 
     arr2[0] = "A"; 
     arr2[1] = "B"; 
     arr2[2] = "C"; 
     arr2[3] = "D"; 

     arr2.GetHashCode(); 

resultados en esta IL (nota, los dos son idénticos)

IL_0002: newarr  [mscorlib]System.String 
    IL_0007: stloc.2 
    IL_0008: ldloc.2 
    IL_0009: ldc.i4.0 
    IL_000a: ldstr  "A" 
    IL_000f: stelem.ref 
    IL_0010: ldloc.2 
    IL_0011: ldc.i4.1 
    IL_0012: ldstr  "B" 
    IL_0017: stelem.ref 
    IL_0018: ldloc.2 
    IL_0019: ldc.i4.2 
    IL_001a: ldstr  "C" 
    IL_001f: stelem.ref 
    IL_0020: ldloc.2 
    IL_0021: ldc.i4.3 
    IL_0022: ldstr  "D" 
    IL_0027: stelem.ref 
    IL_0028: ldloc.2 
    IL_0029: stloc.0 
    IL_002a: ldloc.0 
    IL_002b: callvirt instance int32 [mscorlib]System.Object::GetHashCode() 
    IL_0030: pop 
    IL_0031: ldc.i4.4 
    IL_0032: newarr  [mscorlib]System.String 
    IL_0037: stloc.1 
    IL_0038: ldloc.1 
    IL_0039: ldc.i4.0 
    IL_003a: ldstr  "A" 
    IL_003f: stelem.ref 
    IL_0040: ldloc.1 
    IL_0041: ldc.i4.1 
    IL_0042: ldstr  "B" 
    IL_0047: stelem.ref 
    IL_0048: ldloc.1 
    IL_0049: ldc.i4.2 
    IL_004a: ldstr  "C" 
    IL_004f: stelem.ref 
    IL_0050: ldloc.1 
    IL_0051: ldc.i4.3 
    IL_0052: ldstr  "D" 
    IL_0057: stelem.ref 
    IL_0058: ldloc.1 
    IL_0059: callvirt instance int32 [mscorlib]System.Object::GetHashCode() 
+0

+1 Para la prueba. –

1

me hizo una prueba corta en instantianting una matriz usando la sintaxis que se describe y se encontró esa creación de instancias con valores no predeterminados tomó aproximadamente 2.2 veces más que la instanciación con valores predeterminados.

Cuando cambio y crea una instancia con valores predeterminados, toma aproximadamente la misma cantidad de tiempo.

De hecho, cuando miré el descompilado, parece que lo que ocurre es que la matriz se inicializa y luego se rellena con cualquier valor que no sea el predeterminado.

instanciar con valores no predeterminados:

  bool[] abPrimes = new[] { 
       true, true 
      }; 
0000007e mov   edx,2 
00000083 mov   ecx,79114A46h 
00000088 call  FD3006F0 
0000008d mov   dword ptr [ebp-64h],eax 
00000090 mov   eax,dword ptr [ebp-64h] 
00000093 mov   dword ptr [ebp-54h],eax 
00000096 mov   eax,dword ptr [ebp-54h] 
00000099 cmp   dword ptr [eax+4],0 
0000009d ja   000000A4 
0000009f call  76A9A8DC 
000000a4 mov   byte ptr [eax+8],1 
000000a8 mov   eax,dword ptr [ebp-54h] 
000000ab cmp   dword ptr [eax+4],1 
000000af ja   000000B6 
000000b1 call  76A9A8DC 
000000b6 mov   byte ptr [eax+9],1 
000000ba mov   eax,dword ptr [ebp-54h] 
000000bd mov   dword ptr [ebp-40h],eax 

Instantiating con valores por defecto:

bool[] abPrimes2 = new[] { 
       false, false 
      }; 
000000c0 mov   edx,2 
000000c5 mov   ecx,79114A46h 
000000ca call  FD3006F0 
000000cf mov   dword ptr [ebp-68h],eax 
000000d2 mov   eax,dword ptr [ebp-68h] 
000000d5 mov   dword ptr [ebp-54h],eax 
000000d8 mov   eax,dword ptr [ebp-54h] 
000000db mov   dword ptr [ebp-5Ch],eax 
0

No es posible evitar la inicialización de cada ranura de matriz al valor predeterminado, por lo menos en el nivel de IL.

La cadena es una CLASE, no una estructura.

Eso significa que A, B, C, D y sarray se pueden almacenar en cualquier posición. A, B, C y D pueden obtenerse del grupo Interno, que la referencia al objeto podría ser dinámica.

Pero creo que el JIT podría ser lo suficientemente inteligente como para reducir la mitad de estos gastos generales.

PS. La optimización prematura es la raíz de todo mal.

Cuestiones relacionadas