boost - вон из профессии
От: Kluev  
Дата: 11.06.08 13:07
Оценка: 7 (2) +1 -14 :))) :)
решил сделать небольшой тест. померял скорость работы 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;
}



19.06.08 15:05: Перенесено модератором из 'C/C++' — получился флейм — Кодт
Re: boost - вон из профессии
От: LaptevVV Россия  
Дата: 11.06.08 13:15
Оценка:
Здравствуйте, 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>


А попробуй еще стандартные строковые потоки -интересно сравнить.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: boost - вон из профессии
От: php-coder Чехия http://slava-semushin.blogspot.com
Дата: 11.06.08 13:23
Оценка: 3 (1) +3
Здравствуйте, Kluev, Вы писали:

K>решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда.


Собственно, ничего нового и удивительного:

Но не смотря на свою красоту, универсальность и соответствие общепринятым стандартам преобразования, у boost::lexical_cast есть и следущие недостатки:

1. Низкая скорость работы. По тестам, проведенным Гербом Саттером, результаты которых он описал в своих “Новых сложных задачах на С++”, boost::lexical_cast работает на порядок медленнее, чем тот же sprintf.


и далее:

Два из трех указанных выше недостатков достаточно легко обходятся. Поскольку boost::lexical_cast — это шаблон, то достаточно несложно написать необходимую специализацию, выполняющую преобразование настолько быстро, насколько это необходимо разработчику, а также учитывающую особенности типа wchar_t в VC++.


Взято отсюда: http://sources.ru/wiki/doku.php?id=doc:cpp:boost:lexical_cast
Re: boost - вон из профессии
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 11.06.08 13:28
Оценка:
Здравствуйте, Kluev, Вы писали:

Тоже мне, открытие Америки
Re: мы мним себя в наполеоны...(с)
От: dip_2000 Россия  
Дата: 11.06.08 13:41
Оценка:
Здравствуйте, Kluev, Вы писали:
Сделайте что-то такое же удобное, и безопасное
Re: boost - вон из профессии
От: Zigmar Израиль  
Дата: 11.06.08 13:42
Оценка: 5 (3) +4
Здравствуйте, 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"
Re[2]: мы мним себя в наполеоны...(с)
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 11.06.08 13:49
Оценка:
Здравствуйте, dip_2000, Вы писали:

_>Здравствуйте, Kluev, Вы писали:

_>Сделайте что-то такое же удобное, и безопасное

Вариация на тему:
template<class VAL, class Ch> inline
VAL from_string(const std::basic_string<Ch> &str)
{
    static std::locale loc("Russian_Russia");
    static std::ios_base::iostate st = 0;
    static std::basic_istringstream<Ch> iss;
    VAL ret_val;
    std::use_facet<num_get<Ch, typename std::basic_string<Ch>::const_iterator> >(loc).get(str.begin(), str.end(), iss, st, ret_val);
    return ret_val;
}


Использовать так:
double d = from_string<double>(str);


Можно сравнить по скорости.
Re: boost - вон из профессии
От: Кодт Россия  
Дата: 11.06.08 13:51
Оценка: 2 (2) :)
Здравствуйте, Kluev, Вы писали:

Минус за глупое обобщение в сабже.
Верёвка достаточной длины, чтобы обмотаться сверху донизу и наконец выстрелить в ногу.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: мы мним себя в наполеоны...(с)
От: Kluev  
Дата: 11.06.08 13:56
Оценка: -1
Здравствуйте, dip_2000, Вы писали:

_>Здравствуйте, Kluev, Вы писали:

_>Сделайте что-то такое же удобное, и безопасное

в этом нет ничего трудного, достаточно написать обертку вокруг strtod/strtol
lexical_cast представляет из себя бездарно написанную обертку вокруг iostream,
а iostream в конечном итоге все равно вызывает crt-шные strtod/strtol.
Re: boost - вон из профессии
От: korzh.pavel Россия  
Дата: 11.06.08 13:57
Оценка:
Здравствуйте, Kluev, Вы писали:

K>решил сделать небольшой тест. померял скорость работы boost::lexical_cast, strtod и своего велосипеда.

K>велосипед мне пришлось написать т.к. strtod внутри вызывает strlen и производительность сильно падает на длинных строках.

[...]

мне ещё из подобных средств нравится boost::spirit::real_parser — очень хорошо настраиваемый.
Я один раз встроил его в один проект в котором активно делалось преобразование str->double
Естественно выкинул всё лишнее, работал он быстрее strtod и надёжнее
Автор: korzhik
Дата: 08.08.05
Re[2]: boost - вон из профессии
От: Kluev  
Дата: 11.06.08 14:07
Оценка: +2 -8
Здравствуйте, Zigmar, Вы писали:

Z>boost в данном случае даёт наиболее простое и универсальное решение, которое естественно, не самое быстрое.


Вообще-то нет никаких причин которые мешают написать его по человечески и эффективно.
Вместо этого нагромождение быдлокода, весьма характерное для boost.
Re[2]: boost - вон из профессии
От: CreatorCray  
Дата: 11.06.08 14:14
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>А попробуй еще стандартные строковые потоки -интересно сравнить.

Тоже скорость кошмарная.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: boost - вон из профессии
От: CreatorCray  
Дата: 11.06.08 14:14
Оценка:
Здравствуйте, 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>


Агаа
У меня такая же хрень — велосипеды рулят.

StrToDouble: Done
  CRT     : ( 1.734827)  4'648'555'990
  CrayLib : ( 0.082319)    220'579'670
  Difference : 21.074272


Для int поскромнее — всего в 4 раза разница
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: boost - вон из профессии
От: Zigmar Израиль  
Дата: 11.06.08 14:21
Оценка:
Здравствуйте, 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"
Re[3]: мы мним себя в наполеоны...(с)
От: dip_2000 Россия  
Дата: 11.06.08 14:23
Оценка:
Здравствуйте, Kluev, Вы писали:

K>Здравствуйте, dip_2000, Вы писали:


_>>Здравствуйте, Kluev, Вы писали:

_>>Сделайте что-то такое же удобное, и безопасное

K>в этом нет ничего трудного, достаточно написать обертку вокруг strtod/strtol

K>lexical_cast представляет из себя бездарно написанную обертку вокруг iostream,
K>а iostream в конечном итоге все равно вызывает crt-шные strtod/strtol.

я вас уверяю, по русски, писать гораздо проще(и безопаснее :D ) чем на с++ Вы напишите на с++, и опубликуйте... да хоть здесь. я с удовольствием поставлю вам столько плюсов сколько смогу
Re[4]: boost - вон из профессии
От: Kluev  
Дата: 11.06.08 14:48
Оценка: +1
Здравствуйте, Zigmar, Вы писали:

Z>Здравствуйте, Kluev, Вы писали:

Z>>>boost в данном случае даёт наиболее простое и универсальное решение, которое естественно, не самое быстрое.
K>>Вообще-то нет никаких причин которые мешают написать его по человечески и эффективно.
K>>Вместо этого нагромождение быдлокода, весьма характерное для boost.
Z>Ну и приведите пример универсального решения, которое будет эффективно делать то-же, что и lexical_cast. Не забывая, естественно про поддержку custom types. И вообще, прежде чем наезжать на буст, я бы посоветовал, скажем, заменит строчку "3.1415" на экспоненциальную нотацию или на "NAN" и посмотреть это схавает ваш хвалёный велосипед.

lexical_cast не универсален. например понадобится конвертнуть строку с парой чисел разделенных запятыми. lexical_cast — облом, iostream — облом.
а старые добрые strtod/strtol вполне подойдут (их только нелепый strlen внутри портит).

по настоящему универсальным решением было бы семейство "низкоуровневых" перегруженных функций для разбора чисел + шаблонная обертка вокруг.

template <class Char> int // разбор сишной строки
    parse(double &result, const Char *str);

template <class Char> int // разбор фрагмента строки
    parse(double &result, const Char *&pos, const Char *end);

template <class Char> int // аналогично для интов
    parse(int &result, const Char *str);

template <class Char> int
    parse(int &result, const Char *&pos, const Char *end);

template <class Result, class Char> Result
    lexical_cast(const Char *str)
{
    Result r;
    if (int errcode = parse(r, str))
        throw CastError(errcode);
    return r;
}


для еще более полной универсальности вместо const char* можно использовать итераторы.
Re[4]: мы мним себя в наполеоны...(с)
От: Kluev  
Дата: 11.06.08 15:05
Оценка: +1
Здравствуйте, dip_2000, Вы писали:

на бaзе банальных strtod/l

bool parse(int &r, const char *s)
{
    char *p;
    r = strtol(s, &p, 10);
    if (s == p || errno)
        return false;
    return *p == 0 || isspace((int)*p);
}

bool parse(double &r, const char *s)
{
    char *p;
    r = strtod(s, &p);
    if (s == p || errno)
        return false;
    return *p == 0 || isspace((int)*p);
}

// .....

template <class Result> Result
    lexical_cast(const char *str)
{
    if (!str)
        throw std::exception();

    Result r;
    if (!parse(r, str))
        throw std::exception();
    return r;
}
Re: boost - вон из профессии
От: nen777w  
Дата: 11.06.08 15:07
Оценка:
У меня lexical_cast трудится в калбеках от FLEX парсера.
ИМХО для таких задач возможности lexical_cast это самое то.
Re: premature optimization - туда же
От: Аноним  
Дата: 11.06.08 15:32
Оценка: +2 -2 :))) :)
Re[2]: boost - вон из профессии
От: Sergey Россия  
Дата: 11.06.08 16:16
Оценка:
korzh.pavel пишет:

> мне ещё из подобных средств нравится boost::spirit::real_parser — очень

> хорошо настраиваемый.
> Я один раз встроил его в один проект в котором активно делалось
> преобразование str->double
> Естественно выкинул всё лишнее, работал он быстрее strtod и надёжнее

Со спиритом другая проблема — фиг поймешь, где их глобальный мьютекс
используется, а где нет.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.