| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Тормоза STL |
| Автор: borisbn 7.11.2011, 02:08 | ||||
| Здравствуйте. Потребовалось тут недавно сделать несложную функцию, которая XOR-ит два массива, AND-ит результат с третьим и OR-ит результат в одну переменную. Короче так:
потом решил немного по...вы..делываться и сделал то же самое на STL, только с тремя циклами (один на XOR, второй на AND, третий на аккумулирование). В результате код на STL работает в 6...7 раз медленнее. Подскажите, в чём я не прав. Или это - нормально, а просто не следует сдуру пихать алгоритмы STL во все дыры ? Вот код:
http://liveworkspace.org/code/366eb1fa8b056258fcd9d50b5a3ab4e1 |
| Автор: baldina 7.11.2011, 02:44 |
| три цикла содержат больше вычислений. а если массивы достаточно большие, то гораздо больше перезагрузек кэша, так что 6-7 раз вполне нормально. это не STL плохой, просто задача на 3 цикла действия естественным образом не распадается, это рождение напряженной мысли)) в крайнем случае можно было создать из Ваших трех функций общую функцию (a^b)&c и запихнуть её в accumulate. цикл был бы один и тяга к обобщениям удовлетворена. |
| Автор: volatile 7.11.2011, 03:03 | ||||
| borisbn, не поверите. Взял ваш код. Ничего не менял (код брал на liveworkspace). Скомпилял на студии 2008. Результат :
Прогонял несколько раз. Цифры чуток менялись, но ничего кардинального. на всякий случай комм. строка (оптимизация)
вывод... |
| Автор: boostcoder 7.11.2011, 03:14 |
| volatile, отформатируй плиз строку компилятора. а то экран зашкаливает. Добавлено через 2 минуты и 45 секунд увеличил в 10 раз, но для gen_version() время равно нулю. есть подозрение, что GCC вовсе вырезал тело этой функции. щас проверю.. |
| Автор: boostcoder 7.11.2011, 04:00 | ||||
| так и есть. компилятор вырезал оба вызова gen_version() раньше я уже подымал подобный вопрос. мало того что gen_version() является http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html, так ты еще и возвращаемое значение не проверяешь. поэтому компилятор вполне логично предположил, что функцию можно запросто вырезать. и ведь он не ошибся, все равно никто до сих пор не заметил что она пропала. подкорректировал код так:
http://liveworkspace.org/code/022bb5fb7940d6dacb9ff27ebeff3f95 на LWS оптимизация отключена, поэтому такие огромные расхождения. вот мои результаты. gcc-4.5.2, linux.
странно то, что STL версия почти всегда выполняется быстрее. |
| Автор: Alexeis 7.11.2011, 07:39 |
| Фишка STL в том, что он дебаговой версии много чего проверяет, что делает отладку более простой, а код безопаснее, тогда как в релизе получается, как правило, тоже что и при использовании простого массива. |
| Автор: boostcoder 7.11.2011, 11:08 | ||
не понял. а ты на реальном PC не проверял этот код? |
| Автор: volatile 7.11.2011, 11:58 |
Пардон, никому не хотел доставить неудобство, (кстати в моем браузере ничего не зашкаливает). вставил переводы строк, не знаю как так у вас будет... |
| Автор: boostcoder 7.11.2011, 12:18 |
| volatile, спасибо. все гут. |
| Автор: borisbn 7.11.2011, 12:42 |
в Str operator+( const Str & other ) const; создаётся переменная Str result; так вот, судя по выводу, её конструктор/деструктор не вызывается. Смотри: в main() создаётся 3 переменных (x, y и z) плюс одна переменная result в операторе +, а выводится в cout trace всего из 3-х деструкторов и 3 варианта this. по голове не бить неа. это в воскресенье было. дома компилятор не установлен. |
| Автор: boostcoder 7.11.2011, 12:54 | ||
так у тебя в коде отступы в 4 пробела. ты что, руками на space жал? ибо на LWS работает Tab, но отступы в 3 пробела.
позже. |
| Автор: borisbn 7.11.2011, 16:30 | ||
гы... маленькая хитрость - при переводе строки на LWS отступ делается на 3 символа, но за курсором остаётся ещё один пробел, так что выровняться по 4 - это просто нажать вправо. А если нужно увеличить отступ, то я уже привык на LWS жать Tab, а затем пробел жду. |
| Автор: boostcoder 7.11.2011, 18:05 | ||
в хроме нет никакого пробела. ну да ладно... |
| Автор: boostcoder 8.11.2011, 00:34 | ||
| borisbn, на сколько я понял из того что нагуглил, для получения move semantics нужно использовать http://en.cppreference.com/w/cpp/utility/move, ибо в противном случае, компилятор не сможет выбрать сам какой способ использовать, конструкцию с константной ссылкой, или все же move semantics. т.к. первое не сказывается на вызывающий код, а второе сказывается. http://liveworkspace.org/code/ac113d3f5dab62ac92f0adb2ed7c57bd а вообще, по моему вопросов появилось еще больше. нужно создать отдельную тему по поводу move semantics. Добавлено через 2 минуты и 34 секунды
вот: http://liveworkspace.org/code/dc9fa6e852685d617d5669c31c95a4a4 |
| Автор: mes 8.11.2011, 23:25 | ||
нет, move нужно использовать, тогда когда применение move- семантики не очевидно компилятору.. в остальных он сделает сам.. Добавлено через 2 минуты и 53 секунды Добавлено через 4 минуты и 1 секунду наверно код надо смотреть, там много букв позже гляну.. или подожду обещанной новой темы.. тем более что самому хочется до конца разобраться с этим нововведением.. |
| Автор: Lols 9.11.2011, 00:13 |
| Интересно вы по...выделывались Я так понимаю, что нужно было просто убрать тело функции? (за ненадобностью |
| Автор: boostcoder 9.11.2011, 02:19 |
очень даже может быть. кому нужно? |
| Автор: baldina 9.11.2011, 11:29 |
| move semantics: http://liveworkspace.org/code/04e86bb47f39ea5ab8a75b99f156efcd |
| Автор: boostcoder 9.11.2011, 12:22 |
| baldina, это-то я хорошо понимаю. мне была не понятна ситуация с деструкторами перемещенных объектов. читать тут: http://forum.vingrad.ru/forum/topic-341389.html |