Comments 14
Вывод правильный — пример совершенно не правильный. Все равно что сравнивать производительность memcpy() и memmove().
Сдается мне пример из разряда: «Смотрите, если неправильно девелопить результаты будут плохие. Ваш К.О.»
Если бы выше приложение было сдалано на С++, а не на смеси С/С++, в котором используется для строк, и char*, и std::string, то не было бы никаких проблем с инициализацией строки из char* в std::string, и скорость работы была бы та же самая.
Можно привести контрпример. В программе все строки std::string и мы тратим время на создание буфера char*, копипрования в него строки. В результате видим тормоза, и делаем вывод: Си — тормозной язык.
Если бы выше приложение было сдалано на С++, а не на смеси С/С++, в котором используется для строк, и char*, и std::string, то не было бы никаких проблем с инициализацией строки из char* в std::string, и скорость работы была бы та же самая.
Можно привести контрпример. В программе все строки std::string и мы тратим время на создание буфера char*, копипрования в него строки. В результате видим тормоза, и делаем вывод: Си — тормозной язык.
Так не пробовали?
std::string cstr(str);
for (int i = 0; i < ITERATION_COUNT; ++i)
h2 = hash_stl(cstr);
std::string cstr(str);
for (int i = 0; i < ITERATION_COUNT; ++i)
h2 = hash_stl(cstr);
Очевидно же, при таком подходе не будет создаваться временный объект std::string, в статье же показывается цена инициализации std::string.
Это печально :(
В таком случае смените название статьи на другое. С «Немного о том, почему использование STL бывает неоптимальным», скажем на «Немного о том, почему непонимание работы чего-либо может привести к проблемам».
У вас название статьи намекает что проблема в СТЛ, а это не так.
У вас название статьи намекает что проблема в СТЛ, а это не так.
Во-первых, Вы уж меня извините, это не использование STL, а std::string в программе на C. В среде STL надо было делать вот так:
Вкупе с вмеменным объектом, получается совсем хорошо:
Но главное — нельзя забывать что std::string делается для удобства работы с динамическими строками.
struct hasher: public std::unary_function< const char, void > {
uint32 &res;
inline hasher(uint32 &inp): res(inp){};
inline void operator()( const char c ){res = 31*res + c;};
};
uint32 good_hash_stl(const std::string& str) {
uint32 h = 0;
for_each (str.begin(),str.end(), hasher(h));
return h;
}
Вкупе с вмеменным объектом, получается совсем хорошо:
*************************************
string length: 8 bytes
const char*: 12.35 msec, hash: 312017024
std::string: 3.72 msec, hash: 312017024, 0.30x
propper stl approach: 2.88 msec, hash: 312017024, 0.23x
total allocs: 0
total deallocs: 0
*************************************
string length: 16 bytes
const char*: 19.55 msec, hash: 2657714432
std::string: 8.10 msec, hash: 2657714432, 0.41x
propper stl approach: 6.52 msec, hash: 2657714432, 0.33x
total allocs: 0
total deallocs: 0
*************************************
string length: 32 bytes
const char*: 34.42 msec, hash: 3820028416
std::string: 14.33 msec, hash: 3820028416, 0.42x
propper stl approach: 14.11 msec, hash: 3820028416, 0.41x
total allocs: 0
total deallocs: 0
Но главное — нельзя забывать что std::string делается для удобства работы с динамическими строками.
Вот Вы сначала сделайте копию массива перед передачей указателя в hash_c, а потом можно разговаривать о сравнении 2 вариантов, а пока, это всё — неверное использование инструментов. И называется это не «оптимизация», а исправление ошибок.
Вариант на C можно сделать в один проход, кстати.
uint32 hash_c(const char* str) {
uint32 h = 0;
while (*str)
h = 31*h + *str++;
return h;
}
Соглашусь с коллегами, пост ни о чем да еще и вреден джуниорам, которые вдруг решат что автор прав. Автору нужно немного переосмыслить свое мировоззрение относительно программирования на C++ или же менять профессию.
Sign up to leave a comment.
Немного о том, почему использование STL бывает неоптимальным