решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда.
велосипед мне пришлось написать т.к. strtod внутри вызывает strlen и производительность сильно падает на длинных строках.
результаты, сек
bicycle: 0.135
crt:: 0.682 (в 5 раз медленнее)
boost: 6.289 (в 46.5 раз медленнее велосипеда и в 10 раз медленнее crt)
тест:
#pragma comment(lib, "Winmm.lib")
int main(int argc, char* argv[])
{
DWORD t;
double d, tmp;
const char *str = "3.1415", *end = str + strlen(str);
for (int k = 0; k < 3; k++)
{
// boost
d = 0; t = timeGetTime();
for (int i = 0; i < 1000000; i++)
{
d += lexical_cast<double>(str);
}
t = timeGetTime() - t;
printf("boost: %g: %g\n", d, t*1e-3);
// crt
d = 0; t = timeGetTime();
for (int i = 0; i < 1000000; i++)
{
char *p;
d += strtod(str, &p);
}
t = timeGetTime() - t;
printf("crt: %g: %g\n", d, t*1e-3);
// bicycle
d = 0; t = timeGetTime();
for (int i = 0; i < 1000000; i++)
{
const char *cp;
num_parse(&tmp, &cp, str, end);
d += tmp;
}
t = timeGetTime() - t;
printf("bicycle: %g: %g\n", d, t*1e-3);
}
return 0;
}
Здравствуйте, Kluev, Вы писали:
K>решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда. K>велосипед мне пришлось написать т.к. strtod внутри вызывает strlen и производительность сильно падает на длинных строках.
K>результаты, сек K>
K>bicycle: 0.135
K>crt:: 0.682 (в 5 раз медленнее)
K>boost: 6.289 (в 46.5 раз медленнее велосипеда и в 10 раз медленнее crt)
K>
А попробуй еще стандартные строковые потоки -интересно сравнить.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Kluev, Вы писали:
K>решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда.
Собственно, ничего нового и удивительного:
Но не смотря на свою красоту, универсальность и соответствие общепринятым стандартам преобразования, у boost::lexical_cast есть и следущие недостатки:
1. Низкая скорость работы. По тестам, проведенным Гербом Саттером, результаты которых он описал в своих “Новых сложных задачах на С++”, boost::lexical_cast работает на порядок медленнее, чем тот же sprintf.
и далее:
Два из трех указанных выше недостатков достаточно легко обходятся. Поскольку boost::lexical_cast — это шаблон, то достаточно несложно написать необходимую специализацию, выполняющую преобразование настолько быстро, насколько это необходимо разработчику, а также учитывающую особенности типа wchar_t в VC++.
Здравствуйте, Kluev, Вы писали:
K>решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда. K>велосипед мне пришлось написать т.к. strtod внутри вызывает strlen и производительность сильно падает на длинных строках.
K>результаты, сек K>
K>bicycle: 0.135
K>crt:: 0.682 (в 5 раз медленнее)
K>boost: 6.289 (в 46.5 раз медленнее велосипеда и в 10 раз медленнее crt)
K>
boost в данном случае даёт наиболее простое и универсальное решение, которое естественно, не самое быстрое. Если именно этот кусок у вас является баттлнеком — то и стоит оптимизировать, но для остальных 95% случаев, лучше воспользоваться более читабельным, надёжным и аккуратным решением. Мессадж в названии топика вообще глупый — практически для любой задачи, можно придумать специализированное решение более быстрое чем общее, и это не значит что ради сомнительных микрооптимизаций нужно выкинуть на помойку все удобные и универсальные инструменты.
Конкретно на тему lexical_cast, никто не мешает сделать вам специализацию для вашего конкретного случая. И достоинство его не в том, что он должен, как вам кажется, на синтетическом тесте бить велосипед по скорости конвертирования стрингов в числа, а в том, что это удобный и понятный способ конвертировать любой тип данных в текстовое представление и наоборот.
"To protect people you must slay people. To let people live you must let people die. This is the true teaching of the sword."
-Seijuro Hiko, "Rurouni Kensin"
Здравствуйте, dip_2000, Вы писали:
_>Здравствуйте, Kluev, Вы писали: _>Сделайте что-то такое же удобное, и безопасное
в этом нет ничего трудного, достаточно написать обертку вокруг strtod/strtol
lexical_cast представляет из себя бездарно написанную обертку вокруг iostream,
а iostream в конечном итоге все равно вызывает crt-шные strtod/strtol.
Здравствуйте, Kluev, Вы писали:
K>решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда. K>велосипед мне пришлось написать т.к. strtod внутри вызывает strlen и производительность сильно падает на длинных строках.
[...]
мне ещё из подобных средств нравится boost::spirit::real_parser — очень хорошо настраиваемый.
Я один раз встроил его в один проект в котором активно делалось преобразование str->double
Естественно выкинул всё лишнее, работал он быстрее strtod и надёжнее
Здравствуйте, Zigmar, Вы писали:
Z>boost в данном случае даёт наиболее простое и универсальное решение, которое естественно, не самое быстрое.
Вообще-то нет никаких причин которые мешают написать его по человечески и эффективно.
Вместо этого нагромождение быдлокода, весьма характерное для boost.
Здравствуйте, Kluev, Вы писали:
K>решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда. K>велосипед мне пришлось написать т.к. strtod внутри вызывает strlen и производительность сильно падает на длинных строках.
K>результаты, сек K>
K>bicycle: 0.135
K>crt:: 0.682 (в 5 раз медленнее)
K>boost: 6.289 (в 46.5 раз медленнее велосипеда и в 10 раз медленнее crt)
K>
Здравствуйте, Kluev, Вы писали: Z>>boost в данном случае даёт наиболее простое и универсальное решение, которое естественно, не самое быстрое. K>Вообще-то нет никаких причин которые мешают написать его по человечески и эффективно. K>Вместо этого нагромождение быдлокода, весьма характерное для boost.
Ну и приведите пример универсального решения, которое будет эффективно делать то-же, что и lexical_cast. Не забывая, естественно про поддержку custom types. И вообще, прежде чем наезжать на буст, я бы посоветовал, скажем, заменит строчку "3.1415" на экспоненциальную нотацию или на "NAN" и посмотреть это схавает ваш хвалёный велосипед.
"To protect people you must slay people. To let people live you must let people die. This is the true teaching of the sword."
-Seijuro Hiko, "Rurouni Kensin"
Здравствуйте, Kluev, Вы писали:
K>Здравствуйте, dip_2000, Вы писали:
_>>Здравствуйте, Kluev, Вы писали: _>>Сделайте что-то такое же удобное, и безопасное
K>в этом нет ничего трудного, достаточно написать обертку вокруг strtod/strtol K>lexical_cast представляет из себя бездарно написанную обертку вокруг iostream, K>а iostream в конечном итоге все равно вызывает crt-шные strtod/strtol.
я вас уверяю, по русски, писать гораздо проще(и безопаснее :D ) чем на с++ Вы напишите на с++, и опубликуйте... да хоть здесь. я с удовольствием поставлю вам столько плюсов сколько смогу
Здравствуйте, Zigmar, Вы писали:
Z>Здравствуйте, Kluev, Вы писали: Z>>>boost в данном случае даёт наиболее простое и универсальное решение, которое естественно, не самое быстрое. K>>Вообще-то нет никаких причин которые мешают написать его по человечески и эффективно. K>>Вместо этого нагромождение быдлокода, весьма характерное для boost. Z>Ну и приведите пример универсального решения, которое будет эффективно делать то-же, что и lexical_cast. Не забывая, естественно про поддержку custom types. И вообще, прежде чем наезжать на буст, я бы посоветовал, скажем, заменит строчку "3.1415" на экспоненциальную нотацию или на "NAN" и посмотреть это схавает ваш хвалёный велосипед.
lexical_cast не универсален. например понадобится конвертнуть строку с парой чисел разделенных запятыми. lexical_cast — облом, iostream — облом.
а старые добрые strtod/strtol вполне подойдут (их только нелепый strlen внутри портит).
по настоящему универсальным решением было бы семейство "низкоуровневых" перегруженных функций для разбора чисел + шаблонная обертка вокруг.
korzh.pavel пишет:
> мне ещё из подобных средств нравится boost::spirit::real_parser — очень > хорошо настраиваемый. > Я один раз встроил его в один проект в котором активно делалось > преобразование str->double > Естественно выкинул всё лишнее, работал он быстрее strtod и надёжнее
Со спиритом другая проблема — фиг поймешь, где их глобальный мьютекс
используется, а где нет.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.