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
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?
XCode4 Sekmeler arasında hızlı geçiş y...
Hızlı eğer bir tam sayı iki tamsayı (d...
Π değerini almak için en hızlı yolu ne...
Sin ve cos birlikte hesaplamak için en...
C büyük dosyalar için bir sağlama topl...