SORU
6 ŞUBAT 2009, Cuma


Yapı kullanma zamanı mı?

Zaman yapı ve C sınıfı değil mi kullanmalısınız#? Kavramsal model yapılar madde olduğu zamanlarda kullanılırdeğer türleri sadece bir koleksiyon. Bir şekilde mantıksal olarak hep birlikte birbirine bağlı bir bütün halinde tutmak için.

Bu kurallar arasındahere (cached)geldim:

  • Bir yapı bir tek temsil etmelidir değer.
  • Bir yapı bir hafızaya sahip olmalıdır en az 16 bayt ayak izi.
  • Bir yapı sonra değiştirilmemelidir yaratılış.

Bu kurallar işliyor? Bir yapı anlamsal olarak ne ifade ediyor?

CEVAP
7 AĞUSTOS 2011, Pazar


Kaynak OP tarafından başvurulan bazı güvenilirlik ...ama ne Microsoft hakkında - yapı kullanımıyla ilgili tutumu nedir? Fazladan aradım learning from Microsoft ve ne buldum burada

Bu düşünün bir yapısı yerine tanımlama örnekleri eğer bir sınıf türü küçük ve kısa ömürlü sık veya yaygın olarak gömülü bulunmaktadır diğer nesneler.

Bu tür aşağıdaki özelliklere sahip olmadığı sürece bir yapı tanımlayın:

  1. Bunun mantıklı tek bir değer, ilkel tipleri (integer, double) benzer temsil eder.
  2. Örnek boyutu 16 bayt daha küçük.
  3. Değişmez.
  4. Sık kutulu olmak zorunda değil.

Microsoft sürekli bu kuralları ihlal ediyor

Tamam, #2 ve 3 zaten. Bizim sevgili sözlük 2 iç yapı vardır:

[StructLayout(LayoutKind.Sequential)]  // default for structs
private struct Entry  //<Tkey, TValue>
{
    //  View code at *Reference Source
}

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Enumerator : 
    IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, 
    IDictionaryEnumerator, IEnumerator
{
    //  View code at *Reference Source
}

*Reference Source

'JonnyCantCode.com' kaynak 4 - #4 muhtemelen bir sorun olmaz bu yana oldukça affedilebilir 3 var. Eğer bir yapı kendini boks bulursanız, mimarlığı yeniden düşünmek.

Bakalım Microsoft bu yapılar kullanmak istiyorsunuz neden bak:

  1. Her bir yapı, Entry Enumerator tek değerleri temsil eder.
  2. Hız
  3. Entry asla Sözlük sınıfının dışında bir parametre olarak geçirilir. Daha fazla araştırma IEnumerable uygulanması tatmin etmek için, Sözlük her zaman bir kaptan istenen kopyalar ...mantıklı Enumerator yapı kullandığını gösterir.
  4. Sözlük sınıfa iç. Enumerator Sözlük sayısız ve IEnumerator arayüzü uygulaması - örneğin IEnumerator alıcı eşit erişilebilirlik olması gerekir, çünkü ortak.

Güncelleme- Buna ek olarak, bir yapı, bir arayüz Sayacı gibi uygulayan ve uygulanan tür artığını, yapı referans bir tip olur ve yığın taşındı olduğunu. Sözlük sınıfa iç, Numaralandırıcısıhala bir değer yazın. Ancak, bir yöntem en kısa sürede aramaları GetEnumerator() başvuru tipi: IEnumerator döndürülür.

Burada görmüyoruz ne gereği yapılar sabit tutmak veya 16 bayt veya daha az örnek büyüklüğü sürdürmenin herhangi bir girişim ya da kanıtı

  1. Bu yapılar hiçbir şey üstünde readonly - ilan ettideğildeğişmez
  2. Bu yapı boyutunu 16 bayt olabilir
  3. Entry belirlenmemiş bir ömür (*,* 14*,* 13 veya çöp toplama Add(),) vardır;

Ve ... 4. Her iki yapının hepimiz referans türleri (fazladan bilgi) alabilecek bilmediğiniz TKey ve TValue, saklayın

Karma anahtarları rağmen, sözlük bir yapı örneklerini daha hızlı bir başvuru türü olduğundan kısmen hızlı. Burada, sırayla ile 300,000 rastgele tamsayıları depolayan Dictionary<int, int> anahtarları artan var.

Kapasite: 312874
MemSize: 2660827 bayt
Tamamlanan yeniden Boyutlandırma: 5 ms
Toplam zaman doldurmak için: 889ms

Kapasiteelementlerin iç diziyi daha önce sayısı boyutlandırılmış olmalıdır.

MemSizebir MemoryStream içine sözlük seri ve bayt uzunluğu () amaçlarımız için yeterince doğru alarak belirledi.

Yeniden Boyutlandırma Tamamladı: zaman 312874 elemanları için 150862 elemanları iç diziyi yeniden boyutlandırmak için alır. Her öğe sırayla Array.CopyTo() ile kopyalanan ettiğin zaman o kadar da kötü değil.

Toplam zaman doldurmak için: kuşkusuz günlüğü OnResize bir olay nedeniyle çarpık operasyon sırasında 15 kez yeniden boyutlandırırken kaynağı için; ancak, 300k tamsayılar doldurmak için hala etkileyici ekledim. Sadece meraktan soruyorum, doldurmak için toplam süre ise zaten kapasitesi bilseydi ne olurdu?13ms

Yani, şimdi, Eğer Entry bir sınıf olsaydı? Bu kez ya ölçülerine pek bir farkı olur mu?

Kapasite: 312874
MemSize: 2660827 bayt
Tamamlanan yeniden Boyutlandırma: 26ms
Toplam zaman doldurmak için: 964ms

Açıkçası, en büyük fark yeniden boyutlandırma. Eğer Sözlük Kapasitesi ile başlatılmış ise herhangi bir fark? İle ilgili olarak yeterli değil12ms.

Ne olur, Entry bir yapı olduğu için, bir başvuru türü gibi başlatma gerektirmez. Bu güzellik ve değer yazın felaket hem de. Bir başvuru türü olarak Entry kullanmak için, eklemek için aşağıdaki kodu var:

/*
 *  Added to satisfy initialization of entry elements --
 *  this is where the extra time is spent resizing the Entry array
 * **/
for (int i = 0 ; i < prime ; i  )
{
    destinationArray[i] = new Entry( );
}
/*  *********************************************** */  

Bir başvuru türü olarak Entry Her bir dizi öğesi başlatmak zorunda kaldım nedeni MSDN: Structure Design bulunabilir. Kısacası:

Bir yapı için varsayılan bir kurucu sağlamaz.

Eğer bir yapısı varsayılan yapıcı, dizileri tanımlar yapı, ortak dil çalışma zamanı otomatik olarak oluşturulur varsayılan her bir dizi öğesi kurucu yürütür.

Bazı derleyici, C gibi# derleyicisi, yapı izin vermeyin varsayılan oluşturucular var.

Aslında bu oldukça basit ve Asimov's Three Laws of Robotics ödünç:

  1. Yapı kullanmak için güvenli olmalıdır
  2. Yapı bu 1 numaralı kuralı ihlal edecek sürece işlevini verimli bir şekilde gerçekleştirmek gerekir
  3. Yapı yıkımı kural 1 karşılamak için gerekli olmadığı sürece, kullanımı sırasında sağlam kalması gerekir

...biz bu hürmeti neKısacası, değer türleri ile birlikte sorumludur. Hızlı ve verimlidir, ama çok beklenmedik davranışları düzgün ve doğru bir şekilde muhafaza neden yeteneği (kasıtsız kopya yani).

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ben Schoon

    Ben Schoon

    23 Kasım 2012
  • Matt Davis

    Matt Davis

    4 ŞUBAT 2006
  • the one am radio

    the one am r

    6 Mayıs 2006