Zrobiłem małe porównanie. Za pomocą programu "Zliczanie linii" z załącznika i własnych kompilacji pod c++ oraz C# dla 2 różnych plików. Przy okazji mamy porównanie kompilatorów, jak radzą sobie z takim kodem, bcb i microsftowy.
Na początek, kody których użyłem (C++):
clock_t start, end;
start = clock();
ifstream ifs;
ifs.open ("d:\\file.txt", ifstream::binary);
size_t c;
char data[4096];
size_t n = 0;
while ((c = ifs.read(data, sizeof(data)).gcount()) > 0)
{
for(size_t i = 0; i < c; ++i)
if(data[i] == '\n') ++n;
}
ifs.close();
end = clock();
std::cout << "Time: " << (end - start) ;
(C# console application + .NET framework 4.0)
int b;
int counter
= 0;
var st
= new Stopwatch
();
var buffer
= new byte[4096
];
var sr
= new FileStream
("d:\\file.txt", FileMode.
Open, FileAccess.
Read, FileShare.
None, 4096, FileOptions.
SequentialScan);
st.
Start();
while ((b
= sr.
Read(buffer, 0, buffer.
Length)) > 0
)
for (int i
= 0; i
< b; i
++)
if (buffer
[i
] == '\n')
++counter;
st.
Stop();
Console.
WriteLine(counter
+ " time " + st.
ElapsedMilliseconds);
Wyniki:
Plik 15 MB/150 tys linii
BCB
ifStream | THashedStringList
2.013000 0.140000
1.965000 0.140000
1.950000 0.140000
1.950000 0.140000
MS
C++ | C#
33 ms 127 ms
27 ms 88 ms
26 ms 90 ms
31 ms 88 ms
Plik 300 MB / 3 mln linii
BCB
ifStream | THashedStringList
38.751000 2.902000
38.829000 2.652000
39.016000 2.636000
38.797000 2.605000
MS
C++ | C#
576 ms 1658 ms
576 ms 1721 ms
538 ms 1703 ms
521 ms 1695 ms
Różnica jest jak widać spora. W przypadku przykładu polymorphism(a) wąskim gardłem okazuje się przeliczanie. Dysk przez te 40 sekund praktycznie nie pracował, a procesor wisiał cały czas na 100 %.
THashedStringList, którego odpowiednikiem w C# jest HashSet jak widać jest bardzo szybki. W przypadku MS widać, że biblioteki .NET - w tym przypadku StreamReader jest znacznie wolniejszy mimo, że to tak na prawdę to samo, ale "przyjazność" klas ma swoją cenę.
W obydwu przypadkach programy kompilowane pod Release z maksymalnymi optymalizacjami.