Важливо не плутати оператор перемикання C # з інструкцією перемикача CIL.
Перемикач CIL - це таблиця стрибків, для якої потрібен індекс у наборі адрес стрибків.
Це корисно лише в тому випадку, якщо корпуси перемикача C # суміжні:
case 3: blah; break;
case 4: blah; break;
case 5: blah; break;
Але мало користі, якщо їх немає:
case 10: blah; break;
case 200: blah; break;
case 3000: blah; break;
(Вам знадобиться таблиця розміром до 3000 записів, використовуються лише 3 слоти)
За допомогою суміжних виразів компілятор може почати виконувати лінійні перевірки if-else-if-else.
З більшими суміжними наборами виразів компілятор може починатись з пошуку бінарного дерева та, нарешті, останніх кількох елементів if-else-if-else.
З наборами виразів, що містять скупчення суміжних елементів, компілятор може виконати двійковий пошук по дереву і, нарешті, перемикач CIL.
Це повне "mays" і "mights", і це залежить від компілятора (може відрізнятися від Mono або Rotor).
Я тиражував ваші результати на моїй машині, використовуючи сусідні корпуси:
загальний час для виконання 10-ти напрямного вимикача, 10000 ітерацій (мс): 25.1383
приблизний час на 10-ти перехідний перемикач (мс): 0.00251383
загальний час виконання 50-ти маршрутного комутатора, 10000 ітерацій (мс): 26.593
приблизний час на 50-ти перехідних комутаторів (мс): 0,0026593
загальний час для виконання 5000-ти перемикачів, 10000 ітерацій (мс): 23.7094
приблизний час на 5000 перемикачів (мс): 0,00237094
загальний час для виконання перемикача 50000, 10000 ітерацій (мс): 20.0933
приблизний час на перемикач 50000 (мс): 0.00200933
Тоді я також використовував не суміжні вирази регістру:
загальний час для виконання 10-ти маршрутного комутатора, 10000 ітерацій (мс): 19.6189
приблизний час на 10-ти перемикачів (мс): 0.00196189
загальний час виконання 500-ти маршрутного вимикача, 10000 ітерацій (мс): 19.1664
приблизний час на 500 перемикачів (мс): 0.00191664
загальний час для виконання 5000-ти перемикачів, 10000 ітерацій (мс): 19.5871
приблизний час на 5000 перемикачів (мс): 0.00195871
Не суміжна заява про вимикач 50 000 справ не збирається.
"Вираз занадто довгий або складний для компіляції біля" ConsoleApplication1.Program.Main (string []) "
Тут смішно, що пошук у двійковому дереві виявляється трохи (можливо, не статистично) швидше, ніж інструкція про перемикання CIL.
Брайане, ти вжив слово " константа ", яке має дуже певне значення з точки зору теорії складності обчислювальної техніки. Хоча спрощений суміжний цілий приклад може створювати CIL, який вважається O (1) (константа), розрідженим прикладом є O (log n) (логарифмічний), приклади в кластері лежать десь посередині, а малі приклади - O (n) (лінійний ).
Це навіть не стосується ситуації String, в якій Generic.Dictionary<string,int32>
може бути створена статика , і при першому використанні вона зазнає певних накладних витрат. Продуктивність тут буде залежати від продуктивності Generic.Dictionary
.
Якщо ви перевірте специфікацію мови C # (не специфікацію CIL), ви знайдете "15.7.2 оператор перемикача" не згадує про "постійний час" або що в базовій реалізації навіть використовується інструкція з перемикання CIL (будьте дуже уважні до припущення такі речі).
Зрештою, перемикач C # на цілий вираз у сучасній системі - це субмікросекундна операція, і зазвичай не варто турбуватися.
Звичайно, ці часи залежатимуть від машин та умов. Я б не звертав уваги на ці випробування на хронометраж, тривалість мікросекунди, про яку ми говоримо, деформується будь-яким "реальним" кодом, який виконується (і ви повинні включити якийсь "реальний код", інакше компілятор оптимізує гілку), або тремтіння в системі. Мої відповіді засновані на використанні IL DASM для вивчення CIL, створеного компілятором C #. Звичайно, це не є остаточним, оскільки фактичні інструкції, які виконує ЦП, потім створюються JIT.
Я перевірив остаточні інструкції процесора, фактично виконані на моїй машині x86, і можу підтвердити простий перемикач суміжного набору, виконуючи щось на кшталт:
jmp ds:300025F0[eax*4]
Там, де рядовий пошук у бінарному дереві:
cmp ebx, 79Eh
jg 3000352B
cmp ebx, 654h
jg 300032BB
…
cmp ebx, 0F82h
jz 30005EEE