BOOST, .NET, String.Split и производительность…
От: Denis2005 Россия  
Дата: 16.09.06 11:09
Оценка: 2 (1)
Доброго времени суток!

Понадобилось 'посплитить' строки (вообще задача более сложная, но обо всем по порядку), и по совету “мудрых старцев” (которые по новомодной традиции, при каждом чихе отправляют к 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-а, и по возможности объяснить где "кривые руки"?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.