SORU
9 Ocak 2012, PAZARTESİ


C bir dizede tek karakterleri arasında dolaşmak için en hızlı yolu nedir#?

Başlık soru. Aşağıda, araştırma yoluyla cevap için benim girişimi. Ama yine de bu soruyu çok bilgisiz araştırmam güvenmiyorum C bir dizede tek karakterleri arasında dolaşmak için en hızlı yolu Nedir (#?).

Bazen üzerinden 12* *bir dize tek tek, iç içe belirteçleri için ayrıştırılırken gibi bir karakter döngüsü istiyorum. En hızlı yolu bir dize, özellikle çok büyük dizeleri tek tek karakter sokmanın ne olduğunu merak ediyorum.

Kendimi test bir sürü yaptım ve sonuçlarım aşağıda. Ancak derinlemesine bilgiye çok daha fazlası ile birçok okuyucu var .NET CLR ve C# ise bariz olan bir şeyi kaçırıyorum, ya da eğer benim test kodunda bir hata yaptım bilmiyorum bu yüzden derleyici. Ben senin toplu yanıt istemek. Eğer herkes dize dizin oluşturucu aslında nasıl çalıştığı hakkında fikir varsa, bu çok yardımcı olur. (Bu bir C# dili özelliği, arka planda başka bir şey derlenmiş? Falan CLR?) için inşa edilmiş.

Bir akış kullanarak doğrudan kabul cevabı alınmıştır ilk yöntem konu: how to generate a stream from a string?

Testleri

longString 99.1 milyon karakter bir dize C düz metin sürümü 89 kopyalar oluşan# dil belirtimi. Sonuçlar 20 yineleme için. Nerede bir 'başlangıç' zaman (gibi ilk yineleme örtülü olarak oluşturulan bir dizi yöntem #3), test ettim ayrı ayrı olarak kırılmasını döngü sonra ilk yineleme.

Sonuçları

Benim testleri, char bir dizi ToCharArray kullanarak dize önbellekleme() yöntemi tüm dize üzerinden yineleme için en hızlısıdır. Bu ToCharArray() yöntemi peşin gider ve tek tek karakter için sonraki erişim Endeksi erişimci inşa'den biraz daha hızlıdır.

                                           milliseconds
                                ---------------------------------
 Method                         Startup  Iteration  Total  StdDev
------------------------------  -------  ---------  -----  ------
 1 index accessor                     0        602    602       3
 2 explicit convert ToCharArray     165        410    582       3
 3 foreach (c in string.ToCharArray)168        455    623       3
 4 StringReader                       0       1150   1150      25
 5 StreamWriter => Stream           405       1940   2345      20
 6 GetBytes() => StreamReader       385       2065   2450      35
 7 GetBytes() => BinaryReader       385       5465   5850      80
 8 foreach (c in string)              0        960    960       4

Güncelleme:@Eric'in yorum başına, burada daha normal 1.1 M char dizesi 100'ün üzerinde yineleme için sonuçlar (C birer kopyasını# spec). Dizin oluşturucu ve char dizileri hala en hızlı ve en foreach () string char, akış yöntemleri ile takip edilir.

                                           milliseconds
                                ---------------------------------
 Method                         Startup  Iteration  Total  StdDev
------------------------------  -------  ---------  -----  ------
 1 index accessor                     0        6.6    6.6    0.11
 2 explicit convert ToCharArray     2.4        5.0    7.4    0.30
 3 for(c in string.ToCharArray)     2.4        4.7    7.1    0.33
 4 StringReader                       0       14.0   14.0    1.21
 5 StreamWriter => Stream           5.3       21.8   27.1    0.46
 6 GetBytes() => StreamReader       4.4       23.6   28.0    0.65
 7 GetBytes() => BinaryReader       5.0       61.8   66.8    0.79
 8 foreach (c in string)              0       10.3   10.3    0.11     

Kod (ayrıca; birlikte kısalık için gösterilen test) Kullanılır

//1 index accessor
int strLength = longString.Length;
for (int i = 0; i < strLength; i  ) { c = longString[i]; }

//2 explicit convert ToCharArray
int strLength = longString.Length;
char[] charArray = longString.ToCharArray();
for (int i = 0; i < strLength; i  ) { c = charArray[i]; }

//3 for(c in string.ToCharArray)
foreach (char c in longString.ToCharArray()) { } 

//4 use StringReader
int strLength = longString.Length;
StringReader sr = new StringReader(longString);
for (int i = 0; i < strLength; i  ) { c = Convert.ToChar(sr.Read()); }

//5 StreamWriter => StreamReader 
int strLength = longString.Length;
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(longString);
writer.Flush();
stream.Position = 0;
StreamReader str = new StreamReader(stream);
while (stream.Position < strLength) { c = Convert.ToChar(str.Read()); } 

//6 GetBytes() => StreamReader
int strLength = longString.Length;
MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(longString));
StreamReader str = new StreamReader(stream);
while (stream.Position < strLength) { c = Convert.ToChar(str.Read()); }

//7 GetBytes() => BinaryReader 
int strLength = longString.Length;
MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(longString));
BinaryReader br = new BinaryReader(stream, Encoding.Unicode);
while (stream.Position < strLength) { c = br.ReadChar(); }

//8 foreach (c in string)
foreach (char c in longString) { } 

Cevap kabul:

Aşağıdaki gibi: @CodeİnChaos ve Ben'in notlar yorumladım

fixed (char* pString = longString) {
    char* pChar = pString;
    for (int i = 0; i < strLength; i  ) {
        c = *pChar ;
        pChar  ;
    }
}

Kısa dize 100'ün üzerinde yineleme için yürütme 4.4 ms,&; 0.1 ms st dev lt oldu.

CEVAP
9 Ocak 2012, PAZARTESİ


foreach dahil değil bir sebebi var mı?

foreach (char c in text)
{
    ...
}

Bugerçektenperformans darboğaz olacak bu arada? Ne oranda toplam çalışma süresi yineleme kendisi sürer?

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FrankJavCee

    FrankJavCee

    29 Kasım 2008
  • Justin Schenck

    Justin Schen

    24 Kasım 2006
  • TantalizingTrance

    TantalizingT

    15 ŞUBAT 2009