Re: Оптимизация
От: Roman Odaisky Украина  
Дата: 11.06.08 16:20
Оценка:
Здравствуйте, Kluev, Вы писали:

K>померял скорость работы boost::lexical_cast


Там к нему давно есть оптимизация
Автор: korzhik
Дата: 02.09.06
. Правда, она не вошла в 1.35 — очень уж спешили выпустить новую версию.
До последнего не верил в пирамиду Лебедева.
Re[2]: Оптимизация
От: Аноним  
Дата: 11.06.08 16:36
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

K>>померял скорость работы boost::lexical_cast


RO>Там к нему давно есть оптимизация
Автор: korzhik
Дата: 02.09.06
. Правда, она не вошла в 1.35 — очень уж спешили выпустить новую версию.

Эта оптимизация затрагивает числа с плавающей точкой?
Re[5]: boost - вон из профессии
От: Ligen Украина http://zone-of-ambiguity.blogspot.com/
Дата: 11.06.08 16:49
Оценка: +1 -4
Здравствуйте, Kluev, Вы писали:

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


по своему опыту, у нормального человека довольно редко возникает необходимость засунуть в программу в поле ввода, скажем "бабло:" значение "NAN"
да и экспоненциальная нотация, имхо, хороша только для научных работников и соответствующего им софта
Viva el Junta Militar! Viva el Presidente!
Re[3]: Оптимизация
От: Roman Odaisky Украина  
Дата: 11.06.08 18:01
Оценка:
Здравствуйте, Аноним, Вы писали:

RO>>Там к нему давно есть оптимизация
Автор: korzhik
Дата: 02.09.06
. Правда, она не вошла в 1.35 — очень уж спешили выпустить новую версию.

А>Эта оптимизация затрагивает числа с плавающей точкой?

Именно та — нет. Может, с тех пор уже приделали, не знаю.
До последнего не верил в пирамиду Лебедева.
Re[5]: мы мним себя в наполеоны...(с)
От: dip_2000 Россия  
Дата: 11.06.08 18:13
Оценка:
Здравствуйте, Kluev, Вы писали:

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


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


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

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

K>// .....

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

K>    Result r;
K>    if (!parse(r, str))
K>        throw std::exception();
K>    return r;
K>}
K>


http://www.boost.org/doc/libs/1_35_0/libs/conversion/lexical_cast.htm

//The following example uses numeric data in a string expression: void log_message(const std::string &);

void log_errno(int yoko)
{
    log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
}

быстро, но неудобно
Re[6]: boost - вон из профессии
От: landerhigh Пират  
Дата: 11.06.08 22:50
Оценка: 2 (2) +6 :)
Здравствуйте, Ligen, Вы писали:

L>по своему опыту, у нормального человека довольно редко возникает необходимость засунуть в программу в поле ввода, скажем "бабло:" значение "NAN"

L>да и экспоненциальная нотация, имхо, хороша только для научных работников и соответствующего им софта
Ой, сколько я повидал вырванного волосяного покрова из одного места, когда проектировали исходя из таких вот "редко", "наверное" и "кажется", а на деле оказывалось, что вовсе не редко и именно что кажется.
Re[5]: boost - вон из профессии
От: Zigmar Израиль  
Дата: 11.06.08 23:47
Оценка: 1 (1) +1 :)))
Здравствуйте, Kluev, Вы писали:
K>lexical_cast не универсален. например понадобится конвертнуть строку с парой чисел разделенных запятыми. lexical_cast — облом, iostream — облом.
K>а старые добрые strtod/strtol вполне подойдут (их только нелепый strlen внутри портит).

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


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


Фу, с char* сам работай в С++ коде, а я не мазохист
"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: Спасибо за разоблачение !
От: minorlogic Украина  
Дата: 12.06.08 06:47
Оценка:
Может это заговор с производителями памяти и процессоров ? Может специально делают такие медленные библимотеки ? Чтобы потом было чем грузить процессор?

P.S. Флаги бы компиляции привел, чтоль ... компилятор версию.
А по делу , документацию читать не пробовали ? говорят может помочь ...
Ищу работу, 3D, SLAM, computer graphics/vision.
Re: boost - вон из профессии
От: alexeiz  
Дата: 12.06.08 06:50
Оценка: 2 (1) :)
Здравствуйте, 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: 3.1415e+006: 3.027
crt: 3.1415e+006: 0.639
boost: 3.1415e+006: 3.042
crt: 3.1415e+006: 0.64
boost: 3.1415e+006: 3.042
crt: 3.1415e+006: 0.624

(bicycle implementation was not found in the original post )

Если взглянуть на профайл, что я боюсь, тебе сделать не удалось (по причине либо отсутствия профайлера, либо неумения им пользоваться), то видно, что это очередной micro-benchmark, который ничего не значит. Кстати lexical_cast'а в профайле вообще не видно (оптимизация, понимаешь!).
Level,Function Name,Inclusive Samples,Exclusive Samples,Inclusive Samples %,Exclusive Samples %,Module Name,
0,"lexical_cast_perf.exe","2,183",0,100.00,0.00,"",
0,"_mainCRTStartup","2,183",0,100.00,0.00,"lexical_cast_perf.exe",
4,"[4 rows folded ending in "__fltin2"]",323,12,14.80,0.55,"lexical_cast_perf.exe",
5,"___strgtold12_l",266,188,12.19,8.61,"lexical_cast_perf.exe",
6,"___mtold12",78,78,3.57,3.57,"lexical_cast_perf.exe",
1,"Unknown Frame(s)","1,811",0,82.96,0.00,"UNKNOWN",
2,"_main","1,677",51,76.82,2.34,"lexical_cast_perf.exe",
3,"__Mtxunlock",78,5,3.57,0.23,"lexical_cast_perf.exe",
4,"[ntdll.dll]",67,67,3.07,3.07,"ntdll.dll",
4,"[2 rows folded ending in "_malloc"]",89,12,4.08,0.55,"lexical_cast_perf.exe",
5,"[ntdll.dll]",77,23,3.53,1.05,"ntdll.dll",
4,"[2 rows folded ending in "__Mtxlock"]",93,6,4.26,0.27,"lexical_cast_perf.exe",
5,"[ntdll.dll]",87,87,3.99,3.99,"ntdll.dll",
3,"std::ios_base::_Ios_base_dtor(class std::ios_base *)",106,4,4.86,0.18,"lexical_cast_perf.exe",
4,"std::locale::`scalar deleting destructor'(unsigned int)",96,10,4.40,0.46,"lexical_cast_perf.exe",
4,"[2 rows folded ending in "__Mtxdst"]",79,2,3.62,0.09,"lexical_cast_perf.exe",
5,"[ntdll.dll]",77,15,3.53,0.69,"ntdll.dll",
3,"std::_Mutex::_Mutex(void)",145,7,6.64,0.32,"lexical_cast_perf.exe",
5,"[2 rows folded ending in "[ntdll.dll]"]",74,4,3.39,0.18,"ntdll.dll",
6,"[ntdll.dll]",70,9,3.21,0.41,"ntdll.dll",
3,"std::basic_istream<char,struct std::char_traits<char> >::operator>>(double &)",801,36,36.69,1.65,"lexical_cast_perf.exe",
4,"std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::do_get(class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::ios_base &,int &,double &)const ",650,11,29.78,0.50,"lexical_cast_perf.exe",
5,"std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::_Getffld(char *,class std::istreambuf_iterator<char,struct std::char_traits<char> > &,class std::istreambuf_iterator<char,struct std::char_traits<char> > &,class std::locale const &)const ",168,98,7.70,4.49,"lexical_cast_perf.exe",
6,"[2 rows folded ending in "_strtod"]",335,4,15.35,0.18,"lexical_cast_perf.exe",
8,"[2 rows folded ending in "__fltin2"]",294,8,13.47,0.37,"lexical_cast_perf.exe",
9,"___strgtold12_l",250,164,11.45,7.51,"lexical_cast_perf.exe",
10,"___mtold12",84,83,3.85,3.80,"lexical_cast_perf.exe",


Чтобы удобнее было смотреть, скопируй профайл в .csv файл и открой в Excel'е.

Где здесь что: 5-6 строки — это явный вызов crt strtod, строки 27-28 — вызов strtod из lexical_cast. Производительность lexical_cast определяется полностью выбором basic_istream для преобразования строки в число. Кстати, istream, будучи более общим решением, выбросит исключение, если ему дать не число. А crt ничего не сделает, и будет делать вид, что все нормально. Так что по функциональности эти два подхода не эквивалентны.

Что указывает на то, что это micro-benchmark: начинают выделяться всякие левые вещи и функции, в которых никакой работы не происходит. Здесь это видно на примере Ios_base_dtor, locale::scalar deleting destructor, etc. В обычной программе такого расклада обычно не наблюдается, и соответственно, разницы между lexical_cast и прямым вызовом strtod не будет заметно. Соответственно вывод от сюда такой, что lexical_cast является удовлетворительным решением, пригодным для использования в большинстве случаев. lexical_cast не вносит дополнительного overhead'а по сравнению со стандартной C++-ной библиотекой ввода/вывода.

Конечно, если все что ты делаешь, это перевод миллиона строк в double, то тебе в любом случае нужно специализированное решение. Все существующие библиотечные решения будут медленнее, потому как они расчитаны на более или менее общий случай, а не на твой конкретный.
Re: boost - вон из профессии
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 12.06.08 10:07
Оценка:
Здравствуйте, 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_LEXICAL_CAST_ASSUME_C_LOCALE.
Re[2]: boost - вон из профессии
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 12.06.08 10:14
Оценка:
Здравствуйте, alnsn, Вы писали:

A>Попробуй еще BOOST_LEXICAL_CAST_ASSUME_C_LOCALE.


Поторопился я с ответом, это не работает для чисел с плавающей точкой. Их сложнее оптимизировать, чтобы никто разницы с ostream не заметил.
Re[6]: boost - вон из профессии
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 12.06.08 10:18
Оценка:
Здравствуйте, Ligen, Вы писали:

L>по своему опыту, у нормального человека довольно редко возникает необходимость засунуть в программу в поле ввода, скажем "бабло:" значение "NAN"


Редко то редко, но когда софт упадет на загрузке файла "бабло.приход" из-за NAN ...
Re: boost - вон из профессии
От: Аноним  
Дата: 12.06.08 10:21
Оценка:
Здравствуйте, Kluev, Вы писали:

K>...


Если уж приходится парсить такие объемы данных, на которых становится заметной разница между lexical_cast и strtod, разумнее воспользоваться специализированным решением, написать парсер что ли.
Re[3]: boost - вон из профессии
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 12.06.08 10:27
Оценка:
Здравствуйте, alnsn, Вы писали:

A>>Попробуй еще BOOST_LEXICAL_CAST_ASSUME_C_LOCALE.

A>Поторопился я с ответом, это не работает для чисел с плавающей точкой. Их сложнее оптимизировать, чтобы никто разницы с ostream не заметил.

BTW, давно хочу посмотреть на эту либу: http://article.gmane.org/gmane.comp.lib.boost.user/33648
Re[7]: boost - вон из профессии
От: CreatorCray  
Дата: 12.06.08 10:40
Оценка: 1 (1) +3
Здравствуйте, alnsn, Вы писали:

A>Редко то редко, но когда софт упадет на загрузке файла "бабло.приход" из-за NAN ...

NaN это Not a Number
Не число т.е.
Функция не должна его отрабатывать, а должна вернуть ошибку — мол, фигню подсунули.
Равно как и при попытке подсунуть "ksdhfiwnerxifwer" для преобразования.

В чем проблема то?
Или считаешь что отлов ошибочных данных имеет право делать только boost, а "велосипедная" функция этого уметь не может по определению?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[2]: boost - вон из профессии
От: Kluev  
Дата: 12.06.08 11:24
Оценка: +2 -6
Здравствуйте, alexeiz, Вы писали:

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



A>Если взглянуть на профайл, что я боюсь, тебе сделать не удалось (по причине либо отсутствия профайлера, либо неумения им пользоваться), то видно, что это очередной micro-benchmark, который ничего не значит. Кстати lexical_cast'а в профайле вообще не видно (оптимизация, понимаешь!).


Профайлер здесь и не нужен. Я посмотрел в исходники и обнаружил там быдлокодец вокруг iostream.
Кстати, в недрах этого чуда несколько раз вызывается new, поэтому производительность в реальных условиях будет еще сильно зависить от состояния кучи. А сам факт динамического выделения памяти для операции string -> number говорит о низкой культуре программирования у бустовских кодеров. Видимо на первом месте в бусте стоит "чистота концепций", а все остальные вопросы игнорируются.
Re[8]: boost - вон из профессии
От: Zigmar Израиль  
Дата: 12.06.08 12:27
Оценка:
Здравствуйте, CreatorCray, Вы писали:
CC>NaN это Not a Number
CC>Не число т.е.
CC>Функция не должна его отрабатывать, а должна вернуть ошибку — мол, фигню подсунули.
CC>Равно как и при попытке подсунуть "ksdhfiwnerxifwer" для преобразования.
Ну скажем не NAN, a INF. Хотя в каком-нибудь столбце вполне может стоит и NAN, и далеко не факт что это ошибка, и совершенно точно парсер от такого падать не должен.

CC>В чем проблема то?

CC>Или считаешь что отлов ошибочных данных имеет право делать только boost, а "велосипедная" функция этого уметь не может по определению?
Проблема "велосипедных" функций, в том, что кроме автора (и то, далеко не всегда) не знает что там происходит. В стандартных библиотечных функций, как минимум можно знать чего ожидать, или во всяком случае куда обращаться. Я лично, как-то отыскивая источник memory corruption потратил неделю на чтения мемори дампов и кода, только чтоб обнаружить, что человек, давно в фирме не работающей, когда-то написал "простой" велосипед как-то там конвертирующий строки и числа, и который упал через несколько лет когда в первый раз в неё попала строка с какой-то экзотической локалью, вроде японского.
"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[9]: boost - вон из профессии
От: CreatorCray  
Дата: 12.06.08 13:03
Оценка: +1 -1
Здравствуйте, Zigmar, Вы писали:

Z>Ну скажем не NAN, a INF. Хотя в каком-нибудь столбце вполне может стоит и NAN, и далеко не факт что это ошибка, и совершенно точно парсер от такого падать не должен.

А с чего вдруг ему падать? Откуда такая уверенность что самописное априори хуже библиотечного? Библиотеки по сути такое же сборище велосипедов, и все гарантии качества только на совести их разработчиков и тестеров.
Качество кода (велосипеда или буста или CRT или еще чего) определяется ровностью рук и качеством мозгов программера, их написавшего, и тестера их оттестировавшего.

Z>Проблема "велосипедных" функций, в том, что кроме автора (и то, далеко не всегда) не знает что там происходит.

Для этого есть документирование и комментарии.

Z> В стандартных библиотечных функций, как минимум можно знать чего ожидать, или во всяком случае куда обращаться.

Они ничуть не лучше нормально написанных, оттестированных и задокументированных "велосипедных" функций.

Z> Я лично, как-то отыскивая источник memory corruption потратил неделю на чтения мемори дампов и кода, только чтоб обнаружить, что человек, давно в фирме не работающей, когда-то написал "простой" велосипед как-то там конвертирующий строки и числа, и который упал через несколько лет когда в первый раз в неё попала строка с какой-то экзотической локалью, вроде японского.

Ну так товарищ сам дурак — писать надо нормально. С таким же успехом он мог накосячить в любом другом месте.
Зачем он кстати там писал свое преобразование? Причины на то были?

Если кто не понял — я про то веду речь, что нормально написанный "велосипед" может быть лучше библиотечных функций.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[9]: boost - вон из профессии
От: Kluev  
Дата: 12.06.08 13:18
Оценка: +3 -2
Здравствуйте, Zigmar, Вы писали:

CC>>В чем проблема то?

CC>>Или считаешь что отлов ошибочных данных имеет право делать только boost, а "велосипедная" функция этого уметь не может по определению?
Z>Проблема "велосипедных" функций, в том, что кроме автора (и то, далеко не всегда) не знает что там происходит. В стандартных библиотечных функций, как минимум можно знать чего ожидать, или во всяком случае куда обращаться. Я лично, как-то отыскивая источник memory corruption потратил неделю на чтения мемори дампов и кода, только чтоб обнаружить, что человек, давно в фирме не работающей, когда-то написал "простой" велосипед как-то там конвертирующий строки и числа, и который упал через несколько лет когда в первый раз в неё попала строка с какой-то экзотической локалью, вроде японского.

Из этого не следует, что все велосипеды г-но, а буст хороший. Я прошелся дебаггером по lexical_cast и обнаружил, что качество кода в нем очень низкое. Даже если он одобрен миллионом слепых глаз суть от этого не меняется.
Качество кода определяется самим кодом, а не тем он входит ли он в буст или из доморощенного велосипеда.
Re[10]: boost - вон из профессии
От: . Великобритания  
Дата: 12.06.08 14:40
Оценка: +1
CreatorCray wrote:

> Качество кода (велосипеда или буста или CRT или еще чего) определяется

> ровностью рук и качеством мозгов программера, их написавшего, и тестера
> их оттестировавшего.
Просто обычно у стандартных библиотек гораздо больше тестеров и возможных вариантов использования.

А вообще говоря странно, что тут решили бабло парсить в плавучку.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.