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!
Przekonujesz argument za operatorem '?? =' :) –
@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 –
Nie jest to identyczne, ponieważ '||' wymaga wartości typu Boolean. –