2009-11-24 18 views
8
myFoo = myFoo ?? new Foo(); 

en lugar de¿Mal uso del operador de fusión nulo?

if (myFoo == null) myFoo = new Foo(); 

Estoy en lo correcto al pensar que la primera línea de código siempre se llevará a cabo una misión? Además, ¿se trata de un mal uso del operador nulo-coalescente?

+6

Hace un argumento convincente para el operador '?? =' :) –

+0

@PavelMinaev en este caso, ¿no es idéntico al operador '|| ='? Tendría que reemplazar una llamada 'if (! Isset (myFoo)) myFoo = new Foo();' para garantizar su propio operador –

+0

No es idéntico, ya que '||' requiere un valor booleano. –

Respuesta

19

Comparé el CIL del código generado (asegurándome de hacer una compilación Release - con el código de Optimize marcado en las propiedades del proyecto, que corresponde al interruptor /optimize en csc.exe). Esto es lo que tengo (utilizando VS 2008 - cuenta que Foo.MaybeFoo() es un método que devuelve a veces null, a veces un Foo)

GetFooWithIf:

IL_0000: call  class Application3.Foo Application3.Foo::MaybeFoo() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: brtrue.s IL_000f 
    IL_0009: newobj  instance void Application3.Foo::.ctor() 
    IL_000e: stloc.0 
    IL_000f: ldloc.0 
    IL_0010: ret 

GetFooWithCoalescingOperator:

IL_0000: call  class Application3.Foo Application3.Foo::MaybeFoo() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: dup 
    IL_0008: brtrue.s IL_0010 
    IL_000a: pop 
    IL_000b: newobj  instance void Application3.Foo::.ctor() 
    IL_0010: stloc.0 
    IL_0011: ldloc.0 
    IL_0012: ret 

Por lo tanto, la mismo, excepto por una duplicación de la parte superior superior de la pila y pop. Si esto se puede hacer para hacer una diferencia de rendimiento mensurable, compraré un sombrero específicamente para el propósito de comerlo; por lo tanto, vaya con el que sienta que ofrece una mejor legibilidad.

(corregir) ¡oh, y JITter puede ser lo suficientemente inteligente como para deshacerse de esa diferencia!

+0

¿Esto es con 'csc.exe/optimize +'? –

+0

Creo que sí, editado para aclarar. – AakashM

+0

No sé cuán grande es realmente Foo. ¿Su tamaño afecta el tiempo para ejecutar dup y pop? – Gary

4

Tiene razón en que la primera línea siempre hará una tarea. No me preocuparía a menos que el código se ejecute con mucha frecuencia.

+0

¿Qué debería evitar que el compilador optimice la lectura? – Timbo

+0

@Timbo: no conozco demasiado sobre qué optimizaciones puede o no puede hacer el compilador, pero asumo que 'myFoo' se usará en otro lugar del código y que esto evitaría que el compilador lo optimice. Si no se usa en otro lado, es una historia diferente. –

6

No creo que este sea un mal uso del operador nulo-coalescente. Al leer el código, es lo más breve y conciso posible, y la intención del código es obvia.

Es correcto que al usar el operador nulo-coalescente de esta manera, siempre obtendrá una tarea, pero no me preocuparía por eso. (Y si realmente resulta ser un problema de rendimiento, ya sabes cómo solucionarlo).

Cuestiones relacionadas