C # anahtarı ifadesini CIL anahtarı yönergesiyle karıştırmamak önemlidir.
CIL anahtarı, atlama adresleri kümesine bir dizin gerektiren bir atlama tablosudur.
Bu yalnızca C # anahtarının durumları bitişikse yararlıdır:
case 3: blah; break;
case 4: blah; break;
case 5: blah; break;
Ama eğer değilse çok az kullanım:
case 10: blah; break;
case 200: blah; break;
case 3000: blah; break;
(Sadece 3 yuva kullanılan bir tablo ~ 3000 girişe ihtiyacınız olacaktır)
Bitişik olmayan ifadelerde, derleyici, eğer başka değilse, doğrusal kontroller yapmaya başlayabilir.
Bitişik olmayan daha büyük ifade kümeleriyle, derleyici bir ikili ağaç aramasıyla ve son olarak eğer -eğer-if-else ise son birkaç öğeyle başlayabilir.
Bitişik öğelerin kümelerini içeren ifade kümeleriyle, derleyici ikili ağaç aramasını ve son olarak bir CIL anahtarını içerebilir.
Bu "mays" ve "sayılar" ile doludur ve derleyiciye bağlıdır (Mono veya Rotor ile farklılık gösterebilir).
Sonuçlarınızı bitişikteki durumları kullanarak makinemde çoğalttım:
10 yollu bir anahtar yürütmek için toplam süre, 10000 yineleme (ms):
10 yollu anahtar (ms) için yaklaşık 25.1383: 0.00251383
50 yollu anahtar yürütmek için toplam süre, 10000 yineleme (ms):
50 yollu anahtar (ms) başına 26.593 yaklaşık süre: 0.0026593
5000 yollu bir anahtar yürütmek için toplam süre, 10000 yineleme (ms):
5000 yollu anahtar (ms) için yaklaşık süre 23.7094: 0.00237094
50000 yollu anahtar yürütmek için toplam süre, 10000 yineleme (ms):
50000 yollu anahtar (ms) başına yaklaşık 20.0933: 0.00200933
Sonra da bitişik olmayan vaka ifadeleri kullanarak yaptım:
10 yollu anahtar yürütme için toplam süre, 10000 yineleme (ms):
10 yollu anahtar için yaklaşık süre (ms): 0.00196189
500 yollu anahtar için toplam süre, 10000 yineleme (ms):
500 yollu anahtar için yaklaşık süre (ms): 0.00191664
5000 yollu bir anahtar yürütmek için toplam süre, 10000 yineleme (ms):
5000 yollu anahtar (ms) için yaklaşık süre: 19.5871
Bitişik olmayan 50.000 büyük / küçük harf değişimi ifadesi derlenmez.
"Bir ifade 'ConsoleApplication1.Program.Main (string [])' yakınında derlemek için çok uzun veya karmaşık
Burada komik olan, ikili ağaç aramasının CIL anahtar komutundan biraz daha hızlı (muhtemelen istatistiksel olarak değil) görünmesidir.
Brian, hesaplamalı karmaşıklık teorisi açısından çok açık bir anlamı olan " sabit " kelimesini kullandınız . Basit bitişik tamsayı örneği O (1) (sabit) olarak kabul edilen CIL üretebilirken, seyrek bir örnek O (log n) (logaritmik), kümelenmiş örnekler arasında bir yerde bulunur ve küçük örnekler O (n) (doğrusaldır) ).
Bu, bir statikin Generic.Dictionary<string,int32>
oluşturulabileceği String durumunu bile ele almaz ve ilk kullanımda belirli bir ek yüke maruz kalır. Buradaki performans, performansına bağlı olacaktır Generic.Dictionary
.
Eğer işaretlerseniz C # dil belirtimi (değil CIL Spec) Eğer "15.7.2 switch deyimi" "sabit zaman" ifadesi yer almıyor yapar veya altta yatan uygulama bile CIL anahtarı talimatını kullandığı (varsayarak çok dikkatli olmak bulacaksınız bu tür şeyler).
Günün sonunda, modern bir sistemde bir tamsayı ifadesine karşı bir C # anahtarı, mikrosaniye altı bir işlemdir ve normalde endişelenmeye değmez.
Elbette bu zamanlar makinelere ve koşullara bağlı olacaktır. Bu zamanlama testlerine dikkat etmem, bahsettiğimiz mikrosaniye süreleri çalışmakta olan herhangi bir “gerçek” kod tarafından gölgelenir (ve bazı "gerçek kodları da eklemeniz gerekir, aksi takdirde derleyici dalı optimize eder) veya sistemde titreşim. Yanıtlarım C # derleyicisi tarafından oluşturulan CIL incelemek için IL DASM kullanarak dayanmaktadır . Tabii ki, bu nihai değildir, çünkü CPU'nun çalıştırdığı gerçek talimatlar JIT tarafından oluşturulur.
Aslında x86 makinemde yürütülen son CPU talimatlarını kontrol ettim ve basit bir bitişik set anahtarını aşağıdaki gibi bir şey yaparak onaylayabilirim:
jmp ds:300025F0[eax*4]
İkili ağaç araması aşağıdakilerle dolu olduğunda:
cmp ebx, 79Eh
jg 3000352B
cmp ebx, 654h
jg 300032BB
…
cmp ebx, 0F82h
jz 30005EEE