Re[5]: Выносить вычисление длины выше цикла уже не нужно?
От: IROV..  
Дата: 05.07.11 09:44
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Если _End или _Begin отмечены как volatile — обязан прочитать новые значения при очередном вызове size() и, соответственно, вернуть актуальный размер. Иначе — имеет право не пересчитывать, по крайней мере до С++11.

volatile тут может помочь с решением многопоточности.
И даже если мы обьявим без нее, он все равно будет "вызывать" size — делать отнимание двух поинторов, и производить деление.
Тоесть вычислять актуальный размер, ведь мы можешь изменить его внутри цыкла
я не волшебник, я только учусь!
Re[6]: Выносить вычисление длины выше цикла уже не нужно?
От: IROV..  
Дата: 05.07.11 09:56
Оценка:
Здравствуйте, Erop, Вы писали:

J>>Если не волнует скорость — конечно. Пусть всё по 100500 раз надежно позовет.

E>Всё-таки это надо какой-то мегабыстрый цикл написать, чтобы от того, вынесут .end из цикла или нет что-то зависело
Очень легко, можно получить ускорение в 2-3 раза, но ты этого никогда не найдешь в профайлере, потомучто у тебя везде будет одинаково-тормозить.
Не все на столько грамотные программисты что бы понимать — будет ли оптимизация тут или нет.
Я видел много проектов, где клали на — передачу по ссылке, цыклы с енд, кеширование обращения к синглетонам и тд.
и после моей оптимизации пиковых "багов", осталась толстая прослойка "равномерных" багов, и все сказали следущие — "профайлер не врет!"
Я пожелал удачи )
я не волшебник, я только учусь!
Re[7]: Выносить вычисление длины выше цикла уже не нужно?
От: Erop Россия  
Дата: 05.07.11 10:11
Оценка: :)
Здравствуйте, IROV.., Вы писали:

J>>>Если не волнует скорость — конечно. Пусть всё по 100500 раз надежно позовет.

E>>Всё-таки это надо какой-то мегабыстрый цикл написать, чтобы от того, вынесут .end из цикла или нет что-то зависело
IRO>Очень легко, можно получить ускорение в 2-3 раза, но ты этого никогда не найдешь в профайлере, потомучто у тебя везде будет одинаково-тормозить.
Не затруднит привести какой-нибудь реальный пример такого цикла?
На всяк. случай напомню, что там не должно подставляться тело, чтобы оптимизатор не мог оптимизить...

IRO>Не все на столько грамотные программисты что бы понимать — будет ли оптимизация тут или нет.

IMHO, в большинстве НОРМАЛЬНЫХ циклов это вообще и не надо понимать.
Впрочем жду от тебя контрпримеров.

IRO>Я видел много проектов, где клали на — передачу по ссылке, цыклы с енд, кеширование обращения к синглетонам и тд.

IRO>и после моей оптимизации пиковых "багов", осталась толстая прослойка "равномерных" багов, и все сказали следущие — "профайлер не врет!"
Ну, так и не врёт же. Или ты смог сделать какой-то ЗАМЕР, который бы подтверждал твою правоту? Ну, например, переписал кусок программы в "оптимольном стиле" и кусок стал в 3 раза быстрее?

IRO>Я пожелал удачи

Надеюсь, что ты сделал это доброжелательно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: Выносить вычисление длины выше цикла уже не нужно?
От: IROV..  
Дата: 05.07.11 10:42
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, IROV.., Вы писали:


E>Не затруднит привести какой-нибудь реальный пример такого цикла?

E>На всяк. случай напомню, что там не должно подставляться тело, чтобы оптимизатор не мог оптимизить...
Кстати, еще — сайз в нутри и снаружи это разная семантика.

пример, а почему зразу подставляться тело?
тоесть если подставляеться то надо выносить, а если нет то не надо?


{
  for (int i = 0; i  !=  this->v.size(); ++i)
  {    
    this->v[i] %= 10;
  }
}



чем плох пример?


IRO>>Не все на столько грамотные программисты что бы понимать — будет ли оптимизация тут или нет.

E>IMHO, в большинстве НОРМАЛЬНЫХ циклов это вообще и не надо понимать.
E>Впрочем жду от тебя контрпримеров.
Я с тобой соглашусь, вообще можно много чего не понимать
так делают многие, ты не одинок

IRO>>Я видел много проектов, где клали на — передачу по ссылке, цыклы с енд, кеширование обращения к синглетонам и тд.

IRO>>и после моей оптимизации пиковых "багов", осталась толстая прослойка "равномерных" багов, и все сказали следущие — "профайлер не врет!"
E>Ну, так и не врёт же. Или ты смог сделать какой-то ЗАМЕР, который бы подтверждал твою правоту? Ну, например, переписал кусок программы в "оптимольном стиле" и кусок стал в 3 раза быстрее?
Тебе нужно делать замер что бы понять что передавать стринг по значению это зло?
Если учесть что у них было 100 потоков, и большинство из них более мение активные, и везде юзалось new, меня всегда мучал вопрос сколько времени сьедаеться в синхронизации обращение к этому new

IRO>>Я пожелал удачи

E>Надеюсь, что ты сделал это доброжелательно...
Я когда то был доброжелателен? или это был сарказм )))
я не волшебник, я только учусь!
Re[9]: Выносить вычисление длины выше цикла уже не нужно?
От: Erop Россия  
Дата: 05.07.11 10:56
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Кстати, еще — сайз в нутри и снаружи это разная семантика.

Мы вроде как о случаях, когда одинаковая? То есть, когда выносить .end ТАКИ МОЖНО...

IRO>пример, а почему зразу подставляться тело?

IRO>тоесть если подставляеться то надо выносить, а если нет то не надо?

Если тело полностью подставилось, то у оптимизатора есть все силы и средства для анализа зависимостей. Так что лажать он имеет право только если что-то в теле подставить не удалось...


IRO>
IRO>{
IRO>  for (int i = 0; i  !=  this->v.size(); ++i)
IRO>  {    
    this->>v[i] %= 10;
IRO>  }
IRO>}
IRO>



IRO>чем плох пример?

1) Не понятно, что есть this->v
2) Если это таки std::vector<интегральный тип>, то принятым способом итерации будет таки или через итератор или через стандартный алгоритм какой...
3) На каком компиляторе/опциях оптимизации достигается заявленный разрвы в 2-3 раза?


E>>Впрочем жду от тебя контрпримеров.

IRO>Я с тобой соглашусь, вообще можно много чего не понимать
IRO>так делают многие, ты не одинок
Это всё флуд. Примеры кода будут?

E>>Ну, так и не врёт же. Или ты смог сделать какой-то ЗАМЕР, который бы подтверждал твою правоту? Ну, например, переписал кусок программы в "оптимольном стиле" и кусок стал в 3 раза быстрее?

IRO>Тебе нужно делать замер что бы понять что передавать стринг по значению это зло?
Зависит от значения слова "зло", если под злом понимается, "потеря производительности системы более, чем на 1%", то во многих случаях нужен замер.
Скажем, если программа открывает один файл, считывает из него бинарно три гектара чисел, как-то их слкдывает/вычитает и потом сливает это всё в другой файл, тоже бинарно, то передача там по значению строки с именами этих файлов, скорее всего некритична.

В общем, я хорошо понимаю такой вот аргумент: "Эти мероприятия похволили поднять производительность системы на 25%", а "я вам зуб даю, что там всё медленно" я не понимаю совсем.

IRO>Если учесть что у них было 100 потоков, и большинство из них более мение активные, и везде юзалось new, меня всегда мучал вопрос сколько времени сьедаеться в синхронизации обращение к этому new

1) Это можно легко довольно измерить, вообще-то... Например, какой процент времени работы программы занимало new в целом?
2) Если у людей в программе всё время уходит на синхронизацию new, то вынос/не вынос .end() в/из цикла не должно было ни на что влиять...
3) Если ты правда думаешь, что описанные тобой проблемы являются реальными, перепиши тот продукт на C# и порви тех ребят по производительности


IRO>Я когда-то был доброжелателен? или это был сарказм )))

Это была надежда...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: Выносить вычисление длины выше цикла уже не нужно?
От: IROV..  
Дата: 05.07.11 11:36
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, IROV.., Вы писали:


IRO>>Кстати, еще — сайз в нутри и снаружи это разная семантика.

E>Мы вроде как о случаях, когда одинаковая? То есть, когда выносить .end ТАКИ МОЖНО...
Вроде? я вот уточнил, а ты?


E>Если тело полностью подставилось, то у оптимизатора есть все силы и средства для анализа зависимостей. Так что лажать он имеет право только если что-то в теле подставить не удалось...

правильно, в этом коде это запись в память.


IRO>>
IRO>>{
IRO>>  for (int i = 0; i  !=  this->v.size(); ++i)
IRO>>  {    
    this->>>v[i] %= 10;
IRO>>  }
IRO>>}
IRO>>



IRO>>чем плох пример?

E>1) Не понятно, что есть this->v
std::vector

E>2) Если это таки std::vector<интегральный тип>, то принятым способом итерации будет таки или через итератор или через стандартный алгоритм какой...

Кем принятый? Ты понимаешь что это имеет разную смысловую нагрузку?
Вдруг мне нужен индекс.

E>3) На каком компиляторе/опциях оптимизации достигается заявленный разрвы в 2-3 раза?

http://virtul.livejournal.com/8714.html

E>>>Впрочем жду от тебя контрпримеров.

IRO>>Я с тобой соглашусь, вообще можно много чего не понимать
IRO>>так делают многие, ты не одинок
E>Это всё флуд. Примеры кода будут?
http://virtul.livejournal.com/8714.html

E>>>Ну, так и не врёт же. Или ты смог сделать какой-то ЗАМЕР, который бы подтверждал твою правоту? Ну, например, переписал кусок программы в "оптимольном стиле" и кусок стал в 3 раза быстрее?

IRO>>Тебе нужно делать замер что бы понять что передавать стринг по значению это зло?
E>Зависит от значения слова "зло", если под злом понимается, "потеря производительности системы более, чем на 1%", то во многих случаях нужен замер.
E>Скажем, если программа открывает один файл, считывает из него бинарно три гектара чисел, как-то их слкдывает/вычитает и потом сливает это всё в другой файл, тоже бинарно, то передача там по значению строки с именами этих файлов, скорее всего некритична.
Ищем крайности?
Они использовали ID -> std::string

E>В общем, я хорошо понимаю такой вот аргумент: "Эти мероприятия похволили поднять производительность системы на 25%", а "я вам зуб даю, что там всё медленно" я не понимаю совсем.

Не понимай.

IRO>>Если учесть что у них было 100 потоков, и большинство из них более мение активные, и везде юзалось new, меня всегда мучал вопрос сколько времени сьедаеться в синхронизации обращение к этому new

E>1) Это можно легко довольно измерить, вообще-то... Например, какой процент времени работы программы занимало new в целом?
Можно, они бы могли это проверить но они же такие как ты... "я вам зуб даю, что там всё медленно", а я не их мама, и за их кодом особо как по злорадствовать не лез.
У меня был свой код.

E>2) Если у людей в программе всё время уходит на синхронизацию new, то вынос/не вынос .end() в/из цикла не должно было ни на что влиять...

Трололо +1

E>3) Если ты правда думаешь, что описанные тобой проблемы являются реальными, перепиши тот продукт на C# и порви тех ребят по производительности

Трололо +2

IRO>>Я когда-то был доброжелателен? или это был сарказм )))

E>Это была надежда...
я не волшебник, я только учусь!
Re[11]: не выпендривайся и не найдёшь много новых граблей
От: Erop Россия  
Дата: 05.07.11 12:41
Оценка: 1 (1) -1
Здравствуйте, IROV.., Вы писали:

IRO>>>Кстати, еще — сайз в нутри и снаружи это разная семантика.

E>>Мы вроде как о случаях, когда одинаковая? То есть, когда выносить .end ТАКИ МОЖНО...
IRO>Вроде? я вот уточнил, а ты?

Я не очень понимаю предмет обсуждения.
Если семантика разная, то только одни из двух вариантов верный. То есть речь идёт не об оптимизации, а о РАЗНЫХ алгоритмах. При чём тут вообще этот топик?

IRO>правильно, в этом коде это запись в память.

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


IRO>std::vector

Это хорошо бы показать явно. Если цель в читабельном примере, конечно.

E>>2) Если это таки std::vector<интегральный тип>, то принятым способом итерации будет таки или через итератор или через стандартный алгоритм какой...

IRO>Кем принятый? Ты понимаешь что это имеет разную смысловую нагрузку?
Принятый при разработке на С++. Авторы STL и компилятора рассчитывают на такой сценарий и оптимизируют именно его.
IRO>Вдруг мне нужен индекс.
Я не понял. Мы обсуждаем конкретно этот пример или что-то, что тебе может понадобиться вдруг.


E>>3) На каком компиляторе/опциях оптимизации достигается заявленный разрвы в 2-3 раза?

IRO>http://virtul.livejournal.com/8714.html
Э-э-э? Где?
Там, собственно получили, в конце концов, что если в цикле практически ничего, кроме итерации не делать, то вариант
for(iterator it = v.begin(), it_end = v.end(); it != it_end; ++it) {
    *it = ...
}
является практически лучшим. Вторым по лучшести, уступая всего лишь ПРОЦЕНТЫ является классический для STL way
for( iterator i = v.begin(); i != v.end(); ++i ) {
    *i = ...;
}


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

IRO>http://virtul.livejournal.com/8714.html

Это ни разу не пример РЕАЛЬНОГО кода.
И, тем не менее, даже если рассмотреть вариант, что нам надо вот так заполнить вектор зачем-то, то единственным существенным ускорением этого кода было переписывание функции rand...
Всё остальное -- проценты от производительности.

IRO>Они использовали ID -> std::string

Ну это ОЧЕНЬ зависит от того, что программа делает.
Если она работает со строками, то вообще std::string лучше не использовать, если речь идёт о выжимании перфоманса. Это довольно тормозной шаблон, вообще-то. Его достоинства -- якобы удобство и якобы надёжность, но не скорость...
В частности, если у них строки между нитями не передаются, то можно было завести любую COW-строку, а ещё лучше не любую, а с пулом буферов, устойчивым к фрагментации и lock-free. Но это если это реально основная функциональность и основные тормоза там живут.
А если это просто в лог/отчёт чего-то пишут, то просто пофиг как оно там передаётся.
Ergo: обычно std::string передавать по значению можно. Так как, если надо быстро, то нельзя сам std::string...

IRO>У меня был свой код.

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

IRO>Трололо +1

IRO>Трололо +2
О! У тебя проснудась самокритика.
Так что там с примером РЕАЛЬНОГО цикла, который делает что-то нужное, и который ускоряется в 2-3 раза при переносе .end?
Про ускорение ВСЕГО ЗАПРОСА я даже и не говорю. ХОтя бы ускорение цикла в разы посмотреть бы...

Моё утверждение состоит в том, что такой пример привести не удастся. Вернее удастся, но это будет какой-то редкий, эксклюзивный цикл, нужный в каких-то зитрых условиях и без того вылизываемый до крайности.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: не выпендривайся и не найдёшь много новых граблей
От: IROV..  
Дата: 05.07.11 13:14
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, IROV.., Вы писали:


IRO>>>>Кстати, еще — сайз в нутри и снаружи это разная семантика.

E>>>Мы вроде как о случаях, когда одинаковая? То есть, когда выносить .end ТАКИ МОЖНО...
IRO>>Вроде? я вот уточнил, а ты?

E>Я не очень понимаю предмет обсуждения.

E>Если семантика разная, то только одни из двух вариантов верный. То есть речь идёт не об оптимизации, а о РАЗНЫХ алгоритмах. При чём тут вообще этот топик?

IRO>>правильно, в этом коде это запись в память.

E>И что с того? Поставь опцию оптимизации, ограничивающую предположения о разных указателях на один и тот же объект и будет тебе счастье.
После 2005 студии, по моему такую оптимизацию отключили, из за проблем.
Попробую щас поискать где про это писалось, короче это игра с огоньком. Вот тут то и не стоит оптимизировать ради стабильности алгоритма.


IRO>>std::vector

E>Это хорошо бы показать явно. Если цель в читабельном примере, конечно.
Это имеет большое значение?

E>>>3) На каком компиляторе/опциях оптимизации достигается заявленный разрвы в 2-3 раза?

IRO>>http://virtul.livejournal.com/8714.html
E>Э-э-э? Где?
E>Там, собственно получили, в конце концов, что если в цикле практически ничего, кроме итерации не делать, то вариант
for(iterator it = v.begin(), it_end = v.end(); it != it_end; ++it) {
E>    *it = ...
E>}
является практически лучшим. Вторым по лучшести, уступая всего лишь ПРОЦЕНТЫ является классический для STL way
for( iterator i = v.begin(); i != v.end(); ++i ) {
E>    *i = ...;
E>}

18900.4 — i < v.size();
16353.5 — j < theSize;
11133.4 — i < v.end();
8985.34 — i < i_end;
8772.73 — i < i_end; плюс вынесли запись по глобальном адресном пространстве.

Сможешь проанализировать сам? и выдать сколько же это ПРОЦЕНТИКОВ тут.
Дабы не вводить в заблуждение людей.

IRO>>http://virtul.livejournal.com/8714.html

E>Это ни разу не пример РЕАЛЬНОГО кода.
E>И, тем не менее, даже если рассмотреть вариант, что нам надо вот так заполнить вектор зачем-то, то единственным существенным ускорением этого кода было переписывание функции rand...
E>Всё остальное -- проценты от производительности.
Меня устраивают бесплатные проценты от производительности, а тебя?

IRO>>Они использовали ID -> std::string

E>Ну это ОЧЕНЬ зависит от того, что программа делает.
E>Если она работает со строками, то вообще std::string лучше не использовать, если речь идёт о выжимании перфоманса. Это довольно тормозной шаблон, вообще-то. Его достоинства -- якобы удобство и якобы надёжность, но не скорость...
Поэтому я в свое время сделал свою реализацию ConstString
http://rsdn.ru/forum/cpp/3853558.1.aspx
Автор: IROV..
Дата: 23.06.10

вот код. https://menge-engine.svn.sourceforge.net/svnroot/menge-engine/branches/ConstString3/src/Utils/Core/ConstString.h

E>В частности, если у них строки между нитями не передаются, то можно было завести любую COW-строку, а ещё лучше не любую, а с пулом буферов, устойчивым к фрагментации и lock-free. Но это если это реально основная функциональность и основные тормоза там живут.

E>А если это просто в лог/отчёт чего-то пишут, то просто пофиг как оно там передаётся.
E>Ergo: обычно std::string передавать по значению можно. Так как, если надо быстро, то нельзя сам std::string...
Но когда использовался ID как std::string можно было бы обойтись и копированием только в другие холдеры, вместо того что бы на каждую проверку гонять его туда сюда.

IRO>>У меня был свой код.

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

IRO>>Трололо +1

IRO>>Трололо +2
E>О! У тебя проснудась самокритика.
Нет Трололо детектед проснулся.

E>Так что там с примером РЕАЛЬНОГО цикла, который делает что-то нужное, и который ускоряется в 2-3 раза при переносе .end?

Мне и 10-15% хватит с головой.

E>Про ускорение ВСЕГО ЗАПРОСА я даже и не говорю. ХОтя бы ускорение цикла в разы посмотреть бы...

Запроса?

E>Моё утверждение состоит в том, что такой пример привести не удастся. Вернее удастся, но это будет какой-то редкий, эксклюзивный цикл, нужный в каких-то зитрых условиях и без того вылизываемый до крайности.

Ты просто выкручиваешь вещи, поэтому и не удасться, я бы тебя понимал если бы эта "оптимизация" требовало времени.
А так это просто срать в свой код.

я не волшебник, я только учусь!
Re[3]: Выносить вычисление длины выше цикла уже не нужно?
От: Tilir Россия http://tilir.livejournal.com
Дата: 05.07.11 16:12
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Согласен, с небольшой оговоркой. Если тебе таки надо проитерировать контейнер, то делай это прямо, так, как это принято делать с такими контейнерами.


Да, кстати, верное замечание. Контейнер всегда лучше пробегать его стандартными средствами, чем голым циклом поверх. STL например, в большинстве реализаций, просто хранит специальную затычку на месте end(), которая будет проинлайнена и там будет всё хорошо если написать от begin() до end(). В случае же size() могут быть нюансы. Например в std::list при реализации предпочли splice за O(1), за что у них size вычисляется за O(N). Что при длинных списках и проверке в теле цикла может сказываться убийственно.
Re[3]: А вот и фиг!
От: Tilir Россия http://tilir.livejournal.com
Дата: 05.07.11 16:18
Оценка:
Здравствуйте, Wissenschaftler, Вы писали:

W>Элементарные вещи типа get_size() в большинстве библиотек инлайнятся. Соответственно, компилятор все раскрутит и вынесет.


Не стоит на это уповать. Есть много случаев -- деревья, списки и прочие динамические структуры данных где инлайнить вычисление размера нерационально (см. std::list). Новичку как правило сложно отличить места где магия сработает от мест, где не сработает. Поэтому лучше на неё не надеяться.

Кстати, написанный с явной переменной для размера код будет проще и отлаживать -- есть на что ставить watchpoint, есть где посмотреть что у нас размер оказывается -1 и всё такое.
Re[4]: Выносить вычисление длины выше цикла уже не нужно?
От: IROV..  
Дата: 05.07.11 16:51
Оценка: 8 (1)
Здравствуйте, Tilir, Вы писали:

T>Да, кстати, верное замечание. Контейнер всегда лучше пробегать его стандартными средствами, чем голым циклом поверх. STL например, в большинстве реализаций, просто хранит специальную затычку на месте end(), которая будет проинлайнена и там будет всё хорошо если написать от begin() до end().

Тут нужно еще одну вещь понимать,
for( TVector::iterator it = v.begin(); it != v.end(); ++it);


Хоть v.end() будет заинлайнена, но само значение он будет постояно брать из &v.

Что бы это избежать нужно кешировать.
for( TVector::iterator it = v.begin(), it_end = v.end(); it != it_end; ++it);


я не волшебник, я только учусь!
Re[4]: А вот и фиг!
От: IROV..  
Дата: 05.07.11 17:46
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Не стоит на это уповать. Есть много случаев -- деревья, списки и прочие динамические структуры данных где инлайнить вычисление размера нерационально (см. std::list). Новичку как правило сложно отличить места где магия сработает от мест, где не сработает. Поэтому лучше на неё не надеяться.

В std::vector::size() (MSVC) тоже вычесляеться нерационально, вычитание + деление
я не волшебник, я только учусь!
Re[4]: А вот и фиг!
От: Wissenschaftler http://rsdn_user.livejournal.com
Дата: 05.07.11 19:20
Оценка: +1 -2
Здравствуйте, Tilir, Вы писали:

W>>Элементарные вещи типа get_size() в большинстве библиотек инлайнятся. Соответственно, компилятор все раскрутит и вынесет.


T>Не стоит на это уповать. Есть много случаев -- деревья, списки и прочие динамические структуры данных где инлайнить вычисление размера нерационально (см. std::list). Новичку как правило сложно отличить места где магия сработает от мест, где не сработает. Поэтому лучше на неё не надеяться.

Ага, типа лучше писать, чем думать. Если код критичен по производительности, то новичок найдет, где накосячить. А если не плодить лишние переменные и не забивать голову деталями на каждом шагу, останется больше внимания на красивую декомпозицию задачи и код не придется по 10 раз переписывать.

T>Кстати, написанный с явной переменной для размера код будет проще и отлаживать -- есть на что ставить watchpoint, есть где посмотреть что у нас размер оказывается -1 и всё такое.

Отладчик MSVS кагбэ умеет визуализировать STL-контейнеры, начиная с 2005й студии.
Запретное обсуждение модерирования RSDN:
http://rsdn-user.livejournal.com/652.html
Re[13]: не выпендривайся и не найдёшь много новых граблей
От: Erop Россия  
Дата: 05.07.11 19:59
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>После 2005 студии, по моему такую оптимизацию отключили, из за проблем.

IRO>Попробую щас поискать где про это писалось, короче это игра с огоньком. Вот тут то и не стоит оптимизировать ради стабильности алгоритма.

Она по умолчанию выключена.
Это очень зависит от стиля кодирования. Конкретно у MS с их провайдером STL есть какие-то проблемы с std::list.
Если std::list не использовать, а ещё лучше, не использовать вообще STL, то не всё так плохо

E>>>>3) На каком компиляторе/опциях оптимизации достигается заявленный разрвы в 2-3 раза?

IRO>>>http://virtul.livejournal.com/8714.html
E>>Э-э-э? Где?
E>>Там, собственно получили, в конце концов, что если в цикле практически ничего, кроме итерации не делать, то вариант
for(iterator it = v.begin(), it_end = v.end(); it != it_end; ++it) {
E>>    *it = ...
E>>}
является практически лучшим. Вторым по лучшести, уступая всего лишь ПРОЦЕНТЫ является классический для STL way
for( iterator i = v.begin(); i != v.end(); ++i ) {
E>>    *i = ...;
E>>}

IRO>18900.4 — i < v.size();
IRO>16353.5 — j < theSize;
IRO>11133.4 — i < v.end();
IRO>8985.34 — i < i_end;
IRO>8772.73 — i < i_end; плюс вынесли запись по глобальном адресном пространстве.

IRO>Сможешь проанализировать сам? и выдать сколько же это ПРОЦЕНТИКОВ тут.

Э-э-э, тут маловато статистики -- большой шум. Но даже тут < v.end() проигрывает < i_end как 11 против 9. И это на совсем уже пустом цикле, замечу я в скобках...
При этом, опять же, тут видно, что замороки с size однозначно хуже.
Но это просто ПУСТОЙ цикл. Если цикл делает ЧТО-ТО ЕЩЁ, кроме как организации своих итераций, то разница совсем мизерная будет.
Кстати, в опыте, где нивелировали вклад кэша и шум, результаты отличались совсем немного. Но даже и тут никаких "двух-трёх раз" я пока не наблюдаю.
Два-три раза было бы, если бы против 9000 было 22000, например...

IRO>Меня устраивают бесплатные проценты от производительности, а тебя?

А меня устраивает комплексный подход.
Есть таки затраты на поддержку, на разработку, на перенос.
Так что проценты ни разу не бесплатные...

IRO>Но когда использовался ID как std::string можно было бы обойтись и копированием только в другие холдеры, вместо того что бы на каждую проверку гонять его туда сюда.

Можно. И я бы даже так сделал. Но на производительность программы это скорее всего повлияло бы незаметно.
Я, как бы человек прагматичный. Обычно у меня юзкейс по оптимизации выглядит так. Есть какая-то уже имеющаяся программа. Есть требование заказчика, что всё хорошо, но вот такой-то сценарий надо разогнать в два раза.

И я смотрю, как бы подешевле разогнать.
И я вот очень сомневаюсь, что те меры, про которые ты говоришь, были бы эффективны хоть в какой-нибудь программе


IRO>Запроса?

Ну какой-то осмысленной операции, которую делает твоя программа.

IRO>А так это просто срать в свой код.

Да нет, это просто делать как все. Суть тут в том, что если что-то делать необычно, то имеешь шанс найти необычные грабли. А это лишнее, особенно, если за это ты никакого СУЩЕСТВЕННОГО выигрыша не получаешь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: не выпендривайся и не найдёшь много новых граблей
От: IROV..  
Дата: 05.07.11 20:37
Оценка: -1
Здравствуйте, Erop, Вы писали:

IRO>>Сможешь проанализировать сам? и выдать сколько же это ПРОЦЕНТИКОВ тут.

E>Э-э-э, тут маловато статистики -- большой шум. Но даже тут < v.end() проигрывает < i_end как 11 против 9. И это на совсем уже пустом цикле, замечу я в скобках...
E>При этом, опять же, тут видно, что замороки с size однозначно хуже.
E>Но это просто ПУСТОЙ цикл. Если цикл делает ЧТО-ТО ЕЩЁ, кроме как организации своих итераций, то разница совсем мизерная будет.
E>Кстати, в опыте, где нивелировали вклад кэша и шум, результаты отличались совсем немного. Но даже и тут никаких "двух-трёх раз" я пока не наблюдаю.
E>Два-три раза было бы, если бы против 9000 было 22000, например...
Я не понимаю, ты сам придумал 2-3 раза, если тебе это не надо, не делай, это твои личные проблемы.

IRO>>Меня устраивают бесплатные проценты от производительности, а тебя?

E>А меня устраивает комплексный подход.
E>Есть таки затраты на поддержку, на разработку, на перенос.
E>Так что проценты ни разу не бесплатные...
На какую такую поддержку разработку, и перенос, примеры — или голословность.

IRO>>Но когда использовался ID как std::string можно было бы обойтись и копированием только в другие холдеры, вместо того что бы на каждую проверку гонять его туда сюда.

E>Можно. И я бы даже так сделал. Но на производительность программы это скорее всего повлияло бы незаметно.
E>Я, как бы человек прагматичный. Обычно у меня юзкейс по оптимизации выглядит так. Есть какая-то уже имеющаяся программа. Есть требование заказчика, что всё хорошо, но вот такой-то сценарий надо разогнать в два раза.
Я же тебе не однократно говорил — ты торгаш, и отсюда все твои "особености" мышления.

E>И я смотрю, как бы подешевле разогнать.

E>И я вот очень сомневаюсь, что те меры, про которые ты говоришь, были бы эффективны хоть в какой-нибудь программе
Читай про преждевременую писимизацию.

IRO>>Запроса?

E>Ну какой-то осмысленной операции, которую делает твоя программа.
И что? A+B > B, тебе это стоит доказывать?

IRO>>А так это просто срать в свой код.

E>Да нет, это просто делать как все. Суть тут в том, что если что-то делать необычно, то имеешь шанс найти необычные грабли. А это лишнее, особенно, если за это ты никакого СУЩЕСТВЕННОГО выигрыша не получаешь...
Это обычный коментарий нуба, который не знает как делать, и боиться это использовать.
Просто есть хорошее выступление одного человека, Андрея Плахова, Дзен помоему называеться.
Так там были хорошие слова — Если тебе чтото мешает, сделай так что бы не мешало.
Переведу для тебя, выучи — и ты не найдешь грабли.
я не волшебник, я только учусь!
Re[15]: Перешёл на личности -- значит слил.
От: Erop Россия  
Дата: 05.07.11 23:38
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Я не понимаю, ты сам придумал 2-3 раза,

Э-э-э, дядя, за слова-то свои
Автор: IROV..
Дата: 05.07.11
отвечаешь?

Очень легко, можно получить ускорение в 2-3 раза, но ты этого никогда не найдешь в профайлере, потомучто у тебя везде будет одинаково-тормозить.



Давай, приводи пример, где можно очень легко получить ускорение в 2-3 раза, добавив кэширование .end в циклы...

IRO>Я же тебе не однократно говорил — ты торгаш, и отсюда все твои "особености" мышления.

Перешёл на личности -- значит слил.
Кроме того, я не хочу тебя расстраивать, но программирование давно уже индустрия, и это вовсе не от слова "индус"

IRO>Читай про преждевременую писимизацию.

Пример, или не бывает.

IRO>Это обычный коментарий нуба, который не знает как делать, и боиться это использовать.

Ещё раз перешёл => ещё раз слил.

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

IRO>Так там были хорошие слова — Если тебе чтото мешает, сделай так что бы не мешало.
IRO>Переведу для тебя, выучи — и ты не найдешь грабли.
IRO>

Ты стих Хаяма забыл процитировать.
Я на твоего Андрея Плахова не молюсь, и он для меня в программировании не авторитет.
Кстати, я верно понял, что ты программированию у кинокритика учишься? Или я тебя опять как-то не так понял?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: не выпендривайся и не найдёшь много новых граблей
От: jazzer Россия Skype: enerjazzer
Дата: 06.07.11 00:38
Оценка:
Здравствуйте, Erop, Вы писали:


IRO>>правильно, в этом коде это запись в память.

E>И что с того? Поставь опцию оптимизации, ограничивающую предположения о разных указателях на один и тот же объект и будет тебе счастье.
Почитай уже про эту опцию, Егор, ну в конце-то концов... (и будет тебе счастье)
Она вообще не о том:

-fstrict-aliasing
For C (and C++), this activates optimizations based on the type of expressions. In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same. For example, an "unsigned int" can alias an "int", but not a "void*" or a "double". A character type may alias any other type.

если у тебя есть два int*, то они могут замечательно ссылаться на один и тот же объект и эта опция соответствующий код никогда не будет трактовать как то, что они _не_ могут ссылаться на один и тот же объект. Потому что, например, невозможно станет надежно итерироваться указателями по связным спискам.
Каждый раз, когда ты передаешь указатель по значению, у тебя получаются несколько указателей (исходный и копия) на один и тот же объект — по-твоему, все программы должны просто рухнуть после включения опции, занимающеся такими предположениями, которые ты озвучиваешь
А эта опция лишь предполагает, что если у тебя есть int* и double*, то они не будут указывать на один и тот же адрес.

И какое отношение это имеет в size/end? Там везде один и тот же тип.

E>>>2) Если это таки std::vector<интегральный тип>, то принятым способом итерации будет таки или через итератор или через стандартный алгоритм какой...

При чем тут интегральный тип? С double или CString это не так, что ли?

E>Там, собственно получили, в конце концов, что если в цикле практически ничего, кроме итерации не делать, то вариант
for(iterator it = v.begin(), it_end = v.end(); it != it_end; ++it) {
E>    *it = ...
E>}
является практически лучшим.

А если что-то делать, то он становится худшим, что ли?

E>Вторым по лучшести, уступая всего лишь ПРОЦЕНТЫ является классический для STL way
for( iterator i = v.begin(); i != v.end(); ++i ) {
E>    *i = ...;
E>}

Не очень понятно, почему ты именно второй код называешь классическим, в то время std::for_each и другие стандартные алгоритмы — это первый вариант
Посмотри на сигнатуры в Стандарте — итераторы на конец-начало вычисляются один раз и передаются по значению.
Никто нигде не перевычисляет end().
Так что классический как раз первый.

Ну и "ПРОЦЕНТЫ" — это тоже немало, вообще-то. На моих задачах, по крайней мере.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: А вот и фиг!
От: MasterZiv СССР  
Дата: 06.07.11 06:41
Оценка:
On 05.07.2011 20:18, Tilir wrote:

> Не стоит на это уповать. Есть много случаев -- деревья, списки и прочие

> динамические структуры данных где инлайнить вычисление размера нерационально
> (см. std::list).

size_type size() const
{
return (_Size);
}

Объясни, что тут нерационально инлайнить.
Posted via RSDN NNTP Server 2.1 beta
Re[16]: Перешёл на личности -- значит слил.
От: IROV..  
Дата: 06.07.11 10:17
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, IROV.., Вы писали:


E>Давай, приводи пример, где можно очень легко получить ускорение в 2-3 раза, добавив кэширование .end в циклы...

Я скорее всего отвечал вот на этот закидон.

В любом случае, обычно компилятор формальные проверки делает лучше, чем человек. Так что писать for( int i = 0; i < c.size(); i++) { body(); } НАДЁЖНЕЕ!


18900.4 — i < v.size();
8985.34 — i < i_end;

~2 раза

IRO>>Я же тебе не однократно говорил — ты торгаш, и отсюда все твои "особености" мышления.

E>Перешёл на личности -- значит слил.
Ты стесняешься своей личности? facepalm

E>Кроме того, я не хочу тебя расстраивать, но программирование давно уже индустрия, и это вовсе не от слова "индус"

Есть индустрия — купи-продай, а есть производство, вот ты самый низкий пласт — торгаш.

IRO>>Читай про преждевременую писимизацию.

E>Пример, или не бывает.
Пример как читать? www.google.com

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

IRO>>Так там были хорошие слова — Если тебе чтото мешает, сделай так что бы не мешало.
IRO>>Переведу для тебя, выучи — и ты не найдешь грабли.
IRO>>
E>Ты стих Хаяма забыл процитировать.
E>Я на твоего Андрея Плахова не молюсь, и он для меня в программировании не авторитет.
Он для меня тоже не авторитет, но я его уважаю, и у него есть много правильных и не правильных идей.

E>Кстати, я верно понял, что ты программированию у кинокритика учишься? Или я тебя опять как-то не так понял?

Да да, именно у кинокритика другого от тебя и не мог ожидать.
я не волшебник, я только учусь!
Re[5]: А вот и фиг!
От: IROV..  
Дата: 06.07.11 10:29
Оценка: -1 :)
Здравствуйте, MasterZiv, Вы писали:

MZ>On 05.07.2011 20:18, Tilir wrote:


>> Не стоит на это уповать. Есть много случаев -- деревья, списки и прочие

>> динамические структуры данных где инлайнить вычисление размера нерационально
>> (см. std::list).

MZ>size_type size() const

MZ>{
MZ> return (_Size);
MZ>}

MZ>Объясни, что тут нерационально инлайнить.

Есть листы в которых O(N) не size() а splice()
я не волшебник, я только учусь!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.