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
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:
- Bunun mantıklı tek bir değer, ilkel tipleri (integer, double) benzer temsil eder.
- Örnek boyutu 16 bayt daha küçük.
- Değişmez.
- 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
}
'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:
- Her bir yapı,
Entry
Enumerator
tek değerleri temsil eder. - Hız
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.- 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ı
- Bu yapılar hiçbir şey üstünde
readonly
- ilan ettideğildeğişmez - Bu yapı boyutunu 16 bayt olabilir
Entry
belirlenmemiş bir ömür (*,* 14*,* 13 veya çöp toplamaAdd()
,) 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ç:
- Yapı kullanmak için güvenli olmalıdır
- Yapı bu 1 numaralı kuralı ihlal edecek sürece işlevini verimli bir şekilde gerçekleştirmek gerekir
- 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).
XİBs kullanma zamanı Film Şeridi ve ne...
C numara karşı alaycı kullanma zamanı#...
NSİnteger vs int kullanma zamanı...
Kullanma zamanı RDL raporları üzerinde...
Kullanma zamanı EntityManager.() vs En...