2016-05-26 23 views
5

Küçük bir yapıya sahibim ve tek tek üyeleri kopyalamanın yapıyı tek seferde kopyalamaktan çok daha hızlı olduğunu fark ettim. Bunun için iyi bir neden var mı?Bireysel üyeleri tüm yapısından daha hızlı kopyalayın.

Programım:

// Some random structure 
private struct PackStats 
{ 
    public int nGoodPacks, nBadPacks, nTotalPacks; 
} 

// ... 
PackStats stats1 = new PackStats(); 
PackStats stats2 = new PackStats(); 

// Set some random statistics 
stats1.nGoodPacks = 55; 
stats1.nBadPacks = 3; 
stats1.nTotalPacks = (stats1.nGoodPacks + stats1.nBadPacks); 

// Now assign stats2 from stats1 

// This single line consumes ~190ns... 
stats2 = stats1; 

// ...but these three lines consume ~100ns (in total) 
stats2.nGoodPacks = stats1.nGoodPacks; 
stats2.nBadPacks = stats1.nBadPacks; 
stats2.nTotalPacks = stats1.nTotalPacks; 

nanosaniye aralığında kez ölçmek için, kaç kez atamaları milyonlarca olun:

uint uStart = GetTickCount(); 
for (int nLoop=0; nLoop<10000000; nLoop++) 
{ 
    // Do something... 
} 
uint uElapsed = (GetTickCount() - uStart); 

sonuç etkin ve engelli hem optimizasyonu ile kabaca tutarlı idi .. Bu küçük yapının bireysel üyelerini kopyalamak yaklaşık iki kat daha hızlıydı. Aynı sonuç C/C++ 'da geçerli olur mu?

+0

Burada IL kodunu incelemek hakkında bir yorum yapıldı. Bunu nasıl yapacağınızdan emin değilsiniz ve nasıl yapacağınızı araştıracaksınız. Açıklamak basitse, lütfen yorum yapın. – AlainD

+0

http://stackoverflow.com/q/9025186/11683 – GSerg

+0

64-bit işlemci, anycpu için derlenmiş? –

cevap

3

Zamanlamalarınızın hata ayıklama yapısı için olduğu anlaşılıyor. Benim zamanlamaları aşağıda gösterilmiştir

private void DoIt() 
    { 
     const int numReps = 1000000000; 
     PackStats stats1 = new PackStats(); 
     PackStats stats2 = new PackStats(); 

     stats1.a = 55; 
     stats1.b = 3; 
     stats1.c = stats1.a + stats1.b; 

     for (var i = 0; i < 2; ++i) 
     { 
      var sw1 = Stopwatch.StartNew(); 
      for (var j = 0; j < numReps; ++j) 
      { 
       stats2 = stats1; 
      } 
      sw1.Stop(); 
      Console.WriteLine("Copy struct = {0:N0} ms", sw1.ElapsedMilliseconds); 

      sw1.Restart(); 
      for (var j = 0; j < numReps; ++j) 
      { 
       stats2.a = stats1.a; 
       stats2.b = stats1.b; 
       stats2.c = stats1.c; 
      } 
      sw1.Stop(); 
      Console.WriteLine("Copy fields = {0:N0} ms", sw1.ElapsedMilliseconds); 
     } 
    } 

:

   struct  fields 
Debug/Debug  2,245  1,908 
Debug/No  2,238  1,919 
Release/Debug 287   294 
Release/No  281   275 

Bu Visual Studio 2015 ile programı Herhangi CPU olarak derlenmektedir ve 64- çalıştırılan Bu kod ile aynı testi yaptılar bit makinesi.

ayıklama/ayıklayıcı ayıklamak bağlı (programı çalıştırmak için, yani pres F5) ile işletilen bir ayıklama yapı anlamına gelir. Hata ayıklama/Hayır, hata ayıklama işlemi hata ayıklama olmadan çalıştırıldığı anlamına gelir (örn. Ctrl + F5). Ve Release, elbette, bir sürüm oluşturma anlamına geliyor. Bu bana söyler ne

sürüm modunda, tek seferde bir yapı kopyalama veya tek tek alanları kopyalama arasında neredeyse hiçbir fark olmamasıdır. Burada gösterilen en kötü durumda, bir milyar yineleme üzerinde 6 milisaniye.

Sorunuzun cevabı: "Bütün yapıya daha hızlı bireysel üye Kopya" "Hata ayıklama modunda, evet" gibi görünüyor.

+1

VS 2015, Yayınlama modunda en iyi duruma getirme konusunda daha iyi bir iş çıkarmış gibi görünüyor, bu nedenle bu sonuçlar cesaret vericidir (VS 2008 kullanıyorum). Daha önceki bir cevap, 'stats2 = stats1; 'kullanırken yeni bir yapının yaratıldığına işaret etti, ancak cevap şimdi silindi. Sonuçlarınızla bağ kurduğunuzu sanıyorum - verimli bir optimizatör muhtemelen gereksiz bir şekilde yeni bir yapı oluşturmayı engelleyebilir. – AlainD