SORU
6 Ocak 2009, Salı


En iyi C iki veya daha fazla bayt dizileri birleştirmek *

C 3 bayt dizi var# bir birleştirmek istiyorum. Bu görevi tamamlamak için en etkili yöntem ne olabilir?

CEVAP
6 Ocak 2009, Salı


İlkel türler için (bayt dahil olmak üzere), System.Array.Copy yerine System.Buffer.BlockCopy kullanın. Daha hızlı.

Bir döngü 1 milyon kez idam 10 bayt her 3 dizileri kullanarak önerilen yöntemlerin her sürelerini ölçtüm. İşte sonuçlar:

  1. Yeni bir Bayt DizisiSystem.Array.Copy - 0.2187556 saniye kullanarak
  2. Yeni bir Bayt DizisiSystem.Buffer.BlockCopy - 0.1406286 saniye kullanarak
  3. Ienumerable C# kullanarak verim operatörü - 0.0781270 saniye
  4. Ienumerable Etmeniz kullanarak herhangi bir parametre<>- 0.0781270 saniye

100 element ve re-ran test etmek için her dizi boyutunu arttırdım:

  1. Yeni bir Bayt Dizisi*8- 0.2812554 * saniye kullanarak
  2. Yeni bir Bayt Dizisi*9- 0.2500048 * saniye kullanarak
  3. Ienumerable C# kullanarak verim operatörü - 0.0625012 saniye
  4. Ienumerable Etmeniz kullanarak herhangi bir parametre<>- 0.0781265 saniye

1000 element ve re-ran test etmek için her dizi boyutunu arttırdım:

  1. Yeni bir Bayt DizisiSystem.Array.Copy - 1.0781457 saniye kullanarak
  2. Yeni bir Bayt DizisiSystem.Buffer.BlockCopy - 1.0156445 saniye kullanarak
  3. Ienumerable C# kullanarak verim operatörü - 0.0625012 saniye
  4. Ienumerable Etmeniz kullanarak herhangi bir parametre<>- 0.0781265 saniye

Son olarak, 1 milyon element ve re-ran test etmek için her bir dizinin boyutu, her döngü yürütülüyor arttırdımsadece4000 kez:

  1. Yeni bir Bayt Dizisi- 13.4533833 System.Array.Copy saniye kullanarak
  2. Yeni bir Bayt Dizisi*13- 13.1096267 * saniye kullanarak
  3. Ienumerable kullanarak C# - 0 verim operatör saniye
  4. Ienumerable Etmeniz kullanarak herhangi bir parametre<>Saniye - 0

Eğer yeni bir bayt dizisi ihtiyacınız varsa, kullanın

byte[] rv = new byte[ a1.Length   a2.Length   a3.Length ];
System.Buffer.BlockCopy( a1, 0, rv, 0, a1.Length );
System.Buffer.BlockCopy( a2, 0, rv, a1.Length, a2.Length );
System.Buffer.BlockCopy( a3, 0, rv, a1.Length   a2.Length, a3.Length );

Ama, eğer IEnumerable<byte> bir kullanabilirsinizKESİNLİKLESeri ... ... herhangi bir parametre<^ tercih ederim . yöntem. Sadece C den biraz daha yavaş# kapasiteli santral, ama daha kısa ve daha şık.

IEnumerable<byte> rv = a1.Concat(a2).Concat(a3);

Diziler rastgele bir sayı var ve kullanıyor .Bu gibi System.Buffer.BlockCopy çözüm daha genel yapabilirsiniz 3.5, NET:

private byte[] Combine( params byte[][] arrays )
{
    byte[] rv = new byte[ arrays.Sum( a => a.Length ) ];
    int offset = 0;
    foreach ( byte[] array in arrays ) {
        System.Buffer.BlockCopy( array, 0, rv, offset, array.Length );
        offset  = array.Length;
    }
    return rv;
}

*Not: Yukarıdaki blok çalışmak için üst aşağıdaki ad ekleme gerektirir.

using System.Linq;

DÜZENLEME:Jon Skeet nokta ile ilgili yineleme sonraki veri yapıları (bayt dizi vs IEnumerable), re-ran son zamanlama testi (1 milyon elemanları, 4000 yineleme), ekleme bir döngü olduğunu yineler tam dizi ile her geçişte:

  1. Yeni bir Bayt DizisiSystem.Array.Copy - 78.20550510 saniye kullanarak
  2. Yeni bir Bayt Dizisi*21- 77.89261900 * saniye kullanarak
  3. Ienumerable C# kullanarak verim operatörü - 551.7150161 saniye
  4. Ienumerable Etmeniz kullanarak herhangi bir parametre<>- 448.1804799 saniye

NoktaÇOKhem yaratma etkinliğinin anlaşılabilmesive kullanımıelde edilen veri yapısı. Sadece yaratılış verimlilik odaklı verimsizlik kullanımı ile ilişkili göz ardı edebilir. Şeref, Jon.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • bobono1baby

    bobono1baby

    14 AĞUSTOS 2011
  • FILIPeeeK

    FILIPeeeK

    22 Mayıs 2006
  • stokelycalm

    stokelycalm

    28 Aralık 2010