Доброго времени суток!
Понадобилось 'посплитить' строки (вообще задача более сложная, но обо всем по порядку), и по совету “мудрых старцев” (которые по новомодной традиции, при каждом чихе отправляют к
boost-у) решил потестировать производительность
boost::algoruthm:split.
Честно говоря, результаты меня обескуражили…
Код на C++, STL/BOOST:
int r = 0;
vector<string> tokens(5);
for(int i = 0; i < 1000000; i++)
{
split(tokens, "123 345 asdf 23453 asdfas", is_any_of(" "));
r += tokens.size();
}
cout << r;
Компилятор:
MS VC 8.0
(Релиз)
Опции:
/Ox /Oy /I "C:\WORK\boost_1_32_0\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_VC80_UPGRADE=0x0700" /D "_MBCS" /FD /EHsc /MT /GS- /Gy
/Za /Yu"stdafx.h" /Fp"Release\aaa.pch" /FA /Fa"Release\\" /Fo"Release\\" /Fd"Release\vc80.pdb" /W3 /nologo /c /Wp64 /Zi /TP /errorReport:prompt
/D_SECURE_SCL=0
Время работы:
20 секунд. (и это при полной оптимизации и отключенными проверками !?!)
Код на C#, .NET Framework:
int res = 0;
for(int i = 0; i < 1000000; i++)
res += "123 345 asdf 23453 asdfas".Split(' ').Length;
Console.WriteLine(res);
Время работы: ~1 сек, при 10^7 итераций ~6 сек.
Я уж тут подумал на кривизну рук, но пишу/писал на C++ достаточно долго, еще с первых
GCC,
TCPP 1.0, ..., и с оптимизаторами знаком не понаслышке.
[Есть подозрение на неграмотное дефолтовое аллокирование std::vector и std::string.]
Кстати .NET-ий JIT в Release-е особо не 'химичил' с этим кодом, и честно вызывал split для константной строки и далее inline-ил вызов get_Length() на возвращенном строковом массиве;
Пока переписал с исп. strtok и сделал запасной вариант под .NET.
Может есть что сказать приверженцам BOOST-а, и по возможности объяснить где "кривые руки"?