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

zamiastZłe korzystanie z zerowego operatora koalescencji?

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

Czy mam rację sądząc, że pierwsza linia kodu zawsze wykonać zadanie? Czy jest to złe użycie operatora koalescencyjnego?

+6

Przekonujesz argument za operatorem '?? =' :) –

+0

@PavelMinaev w tym przypadku, czy to nie jest identyczne z operatorem '|| ='? Musi zastąpić wywołanie 'if (! Isset (myFoo)) myFoo = new Foo();' zagwarantować własnego operatora –

+0

Nie jest to identyczne, ponieważ '||' wymaga wartości typu Boolean. –

Odpowiedz

19

Porównałem CIL wygenerowanego kodu (upewniając się, że wykonano kompilację Release - z kodem optymalizacyjnym zaznaczonym we właściwościach projektu, co odpowiada przełącznikowi /optimize na csc.exe). To, co mam (przy użyciu VS 2008 - pamiętać, że Foo.MaybeFoo() jest metodą, która czasami wraca null, czasem 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 

Zatem to samo, z wyjątkiem dodatkowego zwielokrotnienia stosu i popu. Jeśli można to zrobić, aby uzyskać wymierną różnicę w wydajności, kupię kapelusz specjalnie w celu zjedzenia go; w związku z tym wybierz ten, który Twoim zdaniem zapewnia lepszą czytelność.

(edycja) o, a JITter może być na tyle sprytny, aby pozbyć się nawet tej różnicy!

+0

Czy jest to z 'csc.exe/optimize +'? –

+0

Myślę, że tak, zredagowane w celu wyjaśnienia. – AakashM

+0

Nie wiem, jak duży jest naprawdę Foo. Czy rozmiar wpływa na czas uruchamiania dup & pop? – Gary

4

Masz rację, że pierwszy wiersz zawsze będzie wykonywał zadanie. Nie przejmowałbym się tym, chyba że kod jest wykonywany bardzo często.

+0

Co powinno powstrzymać kompilator przed zoptymalizowaniem go? – Timbo

+0

@Timbo: Nie mam zbyt dużej wiedzy na temat optymalizacji, które może wykonać kompilator, ale zakładam, że 'myFoo' będzie używany gdzie indziej w kodzie i że uniemożliwi to optymalizację kompilatora. Jeśli nie jest używany gdzie indziej, jest to inna historia. –

6

Nie uważam tego za złe użycie operatora koalescencyjnego. Czytając kod, jest on tak krótki i zwięzły, jak to tylko możliwe, a intencja kodu jest oczywista.

To prawda, że ​​za pomocą operatora koalesminacji takiego jak to, zawsze otrzymasz zlecenie, ale nie martwię się o to. (A jeśli to naprawdę okazuje się być problemem z wydajnością, już wiesz, jak to naprawić).

Powiązane problemy