Düzenle:
Koşullu işleçle değil, if-else deyimiyle yapılabilecek bir örnek eklendi.
Cevaptan önce, lütfen [ Hangisi daha hızlı? ] Bay Lippert'in blogunda. Bence Sayın Ersönmez'in cevabı buradaki en doğru cevap .
Üst düzey bir programlama diliyle aklımızda tutmamız gereken bir şeyden bahsetmeye çalışıyorum.
Öncelikle, koşullu operatörün C♯'deki if-else deyimiyle daha hızlı veya eşit performansta olması gerektiğini hiç duymadım .
Nedeni basittir, if-else deyimi ile herhangi bir işlem yapılmazsa:
if (i > 0)
{
value += 2;
}
else
{
}
Koşullu operatörün gerekliliği, her iki taraf için de bir değer olması gerektiğidir ve C♯'de her iki tarafın :
da aynı tipte olmasını gerektirir . Bu sadece if-else deyiminden farklı kılar. Böylece sorunuz, makine kodunun talimatının nasıl oluşturulduğunu soran bir soru haline gelir, böylece performans farkı.
Koşullu operatör ile semantik olarak:
İfade ne olursa olsun, bir değer vardır.
Ancak if-else ifadesiyle:
İfade doğru olarak değerlendirilirse, bir şeyler yapın; değilse, başka bir şey yapın.
Bir değer mutlaka if-else deyimiyle ilgili değildir. Varsayımınız yalnızca optimizasyonla mümkündür.
Aralarındaki farkı göstermek için başka bir örnek şöyle olacaktır:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
if(i>0)
array1[1]=4;
else
array2[2]=4;
ancak yukarıdaki kod derlenirse if-else deyimini koşullu işleçle değiştirin, derlemeyeceksiniz:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
(i>0?array1[1]:array2[2])=4; // incorrect usage
Koşullu işleç ve if-else ifadeleri aynı şeyi yaptığınızda aynı kavramsaldır, C koşullu işleçle daha da hızlıdır , çünkü C platformun montajına daha yakındır.
Sağladığınız orijinal kod için, koşullu işleç bir foreach döngüsünde kullanılır ve aralarındaki farkı görmek için işleri karıştırır. Bu yüzden aşağıdaki kodu öneriyorum:
public static class TestClass {
public static void TestConditionalOperator(int i) {
long value=0;
value+=i>0?2:3;
}
public static void TestIfElse(int i) {
long value=0;
if(i>0) {
value+=2;
}
else {
value+=3;
}
}
public static void TestMethod() {
TestConditionalOperator(0);
TestIfElse(0);
}
}
ve aşağıdakiler, optimize edilmiş olan ve olmayan IL'nin iki versiyonudur. Uzun olduklarından, göstermek için bir görüntü kullanıyorum, sağ taraf optimize edilmiş:
(Resmi gerçek boyutunda görmek için tıklayın.)
Her iki kod sürümünde, koşullu işlecin IL'si if-else deyiminden daha kısa görünüyor ve yine de sonunda üretilen makine kodundan şüphe var. Her iki yöntemin talimatları aşağıdadır ve eski görüntü optimize edilmemiştir, ikincisi optimize edilmiştir:
İkincisinde, sarı blok yalnızca eğer çalıştırılırsa kod i<=0
ve mavi blok ise i>0
. Her iki yönerge sürümünde, if-else deyimi daha kısadır.
Farklı talimatlar için [ TÜFE'nin ] mutlaka aynı değildir. Mantıksal olarak, aynı talimat için, daha fazla talimat daha uzun döngüye mal olur. Ancak, talimat alma süresi ve boru / önbellek de dikkate alındıysa, gerçek toplam yürütme süresi işlemciye bağlıdır. İşlemci ayrıca dalları tahmin edebilir.
Modern işlemcilerin daha fazla çekirdeği var, işler bununla daha karmaşık olabilir. Intel işlemci kullanıcısıysanız, [ Intel® 64 ve IA-32 Mimari Optimizasyon Referans Kılavuzu ] 'na göz atmak isteyebilirsiniz .
Donanım tarafından uygulanan bir CLR olup olmadığını bilmiyorum, ancak evet ise, koşullu operatörle muhtemelen daha hızlı olursunuz, çünkü IL açıkça daha azdır.
Not: Tüm makine kodu x86'dır.
DateTime
performansı ölçmek için kullanmayın . KullanınStopwatch
. Daha sonra, zaman daha uzun - ölçmek için çok kısa bir zaman.