2010-11-10 39 views
10

Yapısal olarak ikiye sarılarak ölçü birimi sistemi dediğimi alıyorum. Metre, Ikinci, Derecesi, vb. Gibi C# yapılarım var. Asıl düşüncem, derleyicinin her şeyi sıraladıktan sonra, bir çiftin kullanıldığı gibi bir performans göstermesiydi.Ölçü birimlerini ifade etmek için C# türlerini kullanma

Açık ve örtük işleçlerim basit ve basittir ve derleyici aslında bunları satır içi olarak gösterir, ancak Sayaç ve İkinci olan kod çift kullanılarak aynı koddan 10 kat daha yavaştır.

Sorum şu ki: neden C# derleyicisini, ikinci olarak her zaman satır içi yer alıyorsa çift kullanarak kod kullanarak en uygun kodu kullanamazsınız?

İkinci aşağıdaki gibi tanımlanmıştır:

struct Second 
{ 
    double _value; // no more fields. 

    public static Second operator + (Second left, Second right) 
    { 
     return left._value + right._value; 
    } 
    public static implicit Second operator (double value) 
    { 
     // This seems to be faster than having constructor :) 
     return new Second { _value = value }; 
    } 

    // plenty of similar operators 
} 

Güncelleme:

yapı burada uyuyor diye sormadı. Öyle.

Kodun satır içi çizilip girilmeyeceğini sormadım. JIT bunu satır içi yapar.

Çalışma zamanında gönderilen montaj işlemlerini kontrol ettim. Onlar böyle kodu için farklıydı:

var x = new double(); 
for (var i = 0; i < 1000000; i++) 
{ 
    x = x + 2; 
    // Many other simple operator calls here 
} 

ve bunun gibi: operasyonları aslında inlined edildi yüzden

var x = new Second(); 
for (var i = 0; i < 1000000; i++) 
{ 
    x = x + 2; 
    // Many other simple operator calls here 
} 

sökme hiçbir çağrı talimatları vardı. Ancak fark önemli. Performans testleri, Second'in çift kullanımdan 10 kat daha yavaş olduğunu göstermektedir.

Sorularım (dikkat!): JIT neden IA64 kodu yukarıdaki durumlar için farklıdır? Yapının iki kat hızlı çalışmasını sağlamak için ne yapılabilir? Çifte-İkinci arasında teorik bir fark yok gibi görünüyor, gördüğüm farkın derin nedeni nedir?

+1

bu bir 'implicit' veya '+' operatörüdür? –

+0

Bu konuyla ilgilenebilirsiniz: http://stackoverflow.com/questions/348853/units-of-measure-in-c-almost – Benjol

+1

C# kullandığınızı biliyorum, ama F # olarak düşündünüz mü? Baktığınız gibi bir şey olan statik birimlerin kontrolünü yaptı. Http://stackoverflow.com/questions/40845/how-do-f-units-of-measure-work adresine bakın. –

cevap

1

C# derleyicisi şey satır içi değil - olduğunu yapabilir JIT, bunlarla yükümlü değildir olduğunu. Yine de hızlı olmalıdır. (Aşağıdaki yapıcı kullanımını görmek) gerçi ben muhtemelen + içinde örtük dönüştürme ortadan kaldıracaktır - bir daha operatörü bakmak için:

private readonly double _value; 
public double Value { get { return _value; } } 
public Second(double value) { this._value = value; } 
public static Second operator +(Second left, Second right) { 
    return new Second(left._value + right._value); 
} 
public static implicit operator Second(double value) { 
    return new Second(value); 
} 

JIT inlining belirli senaryolar ile sınırlıdır. Bu kod onları tatmin edecek mi? Anlatması zor - ama çalışmalı ve çoğu senaryo için yeterince hızlı çalışmalıdır. + ile ilgili sorun, çiftlerin eklenmesi için bir IL opcode olmasıdır; neredeyse no no'lu çalışma yapar - kodunuzda birkaç statik yöntem ve kurucu olarak; Her zaman, satır içi satırlarda bile ek yük olacak.

+0

Bir "int" yi bir yapıya (sabit nokta uygulayarak) yaptım ve jitter kodun içine girdiğinde (IMO kodu daha agresif bir şekilde kodlamalı) mükemmel bir montaj kodu üretti. Öyleyse, eğer belirtilmişse, muhtemelen hiçbir yük yoktur. – CodesInChaos

4

Bu benim fikrimdir, katılmıyorumsa, sessiz oylama yerine yorum yazın.

C# Derleyici, satır içi değil. JIT derleyicisi olabilir, ancak bu bizim için belirsizdir çünkü JITer'in davranışı kolay değildir.

double durumunda aslında hiçbir operatör çağrılmaz. İşlenenler, opcode add kullanılarak yığına doğru eklenir. Durumunuzda, op_Add yönteminden yararlanılır ve yığına kopyalama yapmak için üç adet struct kopyalanır.

Optimize etmek için struct'u class ile değiştirerek başlayın. En azından kopya miktarını en aza indirecektir.

+2

... ve yapıları yol boyunca sorun çıkarır. –

+0

Niçin yapıları yerine sınıfları kullanmak istersiniz? Onun sınıfı ile ilgili problemler (devasa sayıdaki operatör ve tipler) 'sınıf' kullanması durumunda değişmeyecek, ancak performans muhtemelen çok düşecek. – CodesInChaos

+0

@CodeInChaos Ben asla 'struct' kullanmayın. Gerçekten sadece birlikte kullanılmasının gerektiğini düşünüyorum. "performans muhtemelen çok düşecek" neden? açıkla lütfen. – Andrey

İlgili konular