Re[28]: Программирование -- деятельность прагматическая? :)
От: Erop Россия  
Дата: 30.08.08 23:44
Оценка:
Здравствуйте, minorlogic, Вы писали:

E>>А когда и зачем надо звать max_element если массив может быть пуст? Зачем проверять факт пустоты массива после вызова max_element, а не до?

M>И это тоже может выбирать програмист.
Прости, конечно, но я всё равно не понял ЗАЧЕМ?...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[21]: Почему преждевременная оптимизация - корень всех зол
От: gear nuke  
Дата: 30.08.08 23:57
Оценка:
Здравствуйте, skeptik_, Вы писали:

_>Поэтому надо было предлагать оба варианта, и интервальный, и контейнерный.


Именно это я и предлагал, извини, что не понятно.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[11]: А ты понятнее объясняй и сам внимательнее читай собе
От: Erop Россия  
Дата: 31.08.08 13:13
Оценка: 18 (1) +1
Здравствуйте, minorlogic, Вы писали:

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

Видимо пример плохой?

А вообщето тебе написали, IMHO, вполне нормальное решение с assert. Оно решает "проблему пустой коллекции", по крайней мере не хуже твоего решения. На мой вкус, так вообе лучше. Ну а ты стал с умным видом утвержать, что это де такая ошибка, и сякая ошибка.

Хотя мне, например, кажется, что
1) Специальные возврааемые значения и
2) Специальные начения входных параметров — это если и не ошибки проектирования, то точно уж кривизна диайна.

И что я вижу? Что то решение, которое ты выаёшь за эталон, действует так: "возвраает итратор максимального элемента, либо возвращает end, если диапазон пуст". А решение, которое ты счёл неправильным, устроено так: "возвращает максимальный элемент непустой коллекции".
IMHO нет специального случая на входе и специального значения на выходе...

В любом случае ты так и не ответил чем код
IT res = max_element( beg, end );
if( res != end ) {
    process( res );
}
лучше кода
if( beg != end ) {
    process( max_element( beg, end ) ); 
}


Тем что в первом варианте лишняя проверка выполняется и логика проверки корректности входных данных вывернутая?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[21]: А в чём проблемы?
От: Erop Россия  
Дата: 31.08.08 13:22
Оценка:
Здравствуйте, skeptik_, Вы писали:

_>А теперь попробуй применить твою функцию в данном коде:

_>
_>template< typename RandomAccessIterator >
_>void selection_sort( RandomAccessIterator first, RandomAccessIterator last )
_>{
_>    while( first < --last )
_>        std::iter_swap( last, std::max_element( first, last + 1 ) );
_>}
_>


А в чём проблема? Если уж first < last, то first < last + 1 тем более
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[22]: А в чём проблемы?
От: skeptik_  
Дата: 31.08.08 14:23
Оценка:
Здравствуйте, Erop, Вы писали:

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


_>>А теперь попробуй применить твою функцию в данном коде:

_>>
_>>template< typename RandomAccessIterator >
_>>void selection_sort( RandomAccessIterator first, RandomAccessIterator last )
_>>{
_>>    while( first < --last )
_>>        std::iter_swap( last, std::max_element( first, last + 1 ) );
_>>}
_>>


E>А в чём проблема? Если уж first < last, то first < last + 1 тем более

Читай внимательнее, речь о функции
template<class Container>
typename Container::value_type& max_element( Container& c )
{
    if ( c.empty() )
        throw range_error();
    typename Container::iterator result = c.begin();
    for( typename Container::iterator i = result; i < c.end(); ++i )
        if ( *result < *i )
            result = i;
    return *result;
}
Re: Почему преждевременная оптимизация - корень всех зол?
От: EyeOfHell Россия eyeofhell.habr.ru
Дата: 31.08.08 20:15
Оценка:

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


Внесу свои три рубля. Я конечно могу ошибаться и все нижеизложенное — сугубо мое мнение, но дело в статистике . В массе случаев время, потраченное на предварительную оптимизацию будет больше, нежели время, потраченное на оптимизацию только тормозящих мест после того как все готово.

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

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


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

Вот у меня недавно проект был. Сделал бету, запустил тесты — тормоза. Посмотрел по профайлеру — равномерно размазаны. Огорчился. Потестировал глубже — оказалось бага в алгоритме, код вызывался просто чаще чем нужно. Исправил две строки, скорость стала как полагается по спецификации.

А если бы с самого начала все оптимизировал... Было бы грустно, печально и долго. Вот.
Re[4]: Почему преждевременная оптимизация - корень всех зол?
От: Кэр  
Дата: 02.09.08 02:52
Оценка: +3 -1
Здравствуйте, jazzer, Вы писали:

J>>>если тормоза уже заметны, то, очевидно, это уже не преждевременная оптимизация

Кэр>>Осталось ответить на вопрос — как они заметны? "На глазок"?

J>Да, "на глазок".

J>Поэтому что у пользователя будет глазок, очень похожий на твой,
J>...
J>Так что это ни разу не преждевременная оптимизация, а самая что ни на есть обычная.
Перечитайте оригинальную цитату:
http://rsdn.ru/forum/message/3066911.1.aspx
Автор: drol
Дата: 18.08.08


Перечитайте вот эту ссылку:
http://www.flounder.com/optimization.htm

Ваш "глазок" сможет детектировать только общую проблему. Очень (очень!) редко анализ работы программы и ее кода сам по себе подскажет, где решение проблемы. Поможет тут только профайлер запущенный на реальных данных. Разговоры про оптимизацию без замеров профайлера — пустое сотрясание воздуха. И уж точно не разговор инженеров.

J>А профайлер только поможет найти конкретное место, которое надо оптимизировать, не более того.

Ну да. Всего навсего покажет что является проблемой. Куда уж ему до "глазка"

J>а тебе совсем не хочется, чтобы твои пользователи на весь мир о твоем софте кричали, что он тормозной, если, конечно, ты не Microsoft

Если вы хотите, чтобы ваши шутки ценились за остроумие — шутите умно и смешно. Если конечно вы не Петросян
Re[5]: Почему преждевременная оптимизация - корень всех зол?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 02.09.08 04:29
Оценка: -1
Здравствуйте, Кэр, Вы писали:
...
J>>А профайлер только поможет найти конкретное место, которое надо оптимизировать, не более того.
Кэр>Ну да. Всего навсего покажет что является проблемой. Куда уж ему до "глазка"

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

Учитывая правило 80/20, локализация проблемных мест обычно не вызывает каких-либо серьезных затруднений (при достаточном уровне "понимания" проекта, иначе мы с очень большой долей вероятности будем оптимизировать не то).
Re[6]: Почему преждевременная оптимизация - корень всех зол?
От: Кэр  
Дата: 02.09.08 04:47
Оценка: +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Используя данные оптимизатора, мы рискуем начать оптимизировать отдельные шаги (это то, куда покажет оптимизатор), оставив за бортом более высокоуровневые проблемы, от решения которых отдача намного больше.

ЮЖ>Учитывая правило 80/20, локализация проблемных мест обычно не вызывает каких-либо серьезных затруднений (при достаточном уровне "понимания" проекта, иначе мы с очень большой долей вероятности будем оптимизировать не то).

Оригинальные рассуждения. Программирование вообще штука опасная — мало ли чего можно накодировать. Если мы не доверяем самим себе, боясь узнать реальные данные от профайлера — они де нас могут обмануть; то я уж не знаю, как дальше можно работать. Разве что уповая на абстрактные правила 80/20.
Re[7]: Почему преждевременная оптимизация - корень всех зол?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 02.09.08 20:30
Оценка:
Здравствуйте, Кэр, Вы писали:

Кэр>Здравствуйте, Юрий Жмеренецкий, Вы писали:


Кэр> Если мы не доверяем самим себе, боясь узнать реальные данные от профайлера — они де нас могут обмануть;

Я совсем про другое писал.
Re[8]: Почему преждевременная оптимизация - корень всех зол?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.08 04:17
Оценка: 1 (1) +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:


Кэр>> Если мы не доверяем самим себе, боясь узнать реальные данные от профайлера — они де нас могут обмануть;

ЮЖ>Я совсем про другое писал.
Ну. Ты писал что а) используя данные от профайлера, есть риск оптимизировать не то. А что, не используя данные профайлера, этот риск как-то уменьшается? За счет чего?
Далее, ты писал, что "обычно" легко идентифицировать проблемные места. Практика показывает, что нифига не легко. Даже при 100% понимании проекта. Потому, что скорость может теряться вовсе не там, где кажется. Вон недавно в веб программировании парень пытался понять, почему страничка долго грузится. Ему уж успели насоветовать советов по экономии трафика. А оказалось, что Bottleneck — в том, как IE парсит CSS. Ну и что можно было сделать без помощи профайлера?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Почему преждевременная оптимизация - корень всех зол?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 03.09.08 11:00
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Юрий Жмеренецкий, Вы писали:



Кэр>>> Если мы не доверяем самим себе, боясь узнать реальные данные от профайлера — они де нас могут обмануть;

ЮЖ>>Я совсем про другое писал.
S>Ну. Ты писал что а) используя данные от профайлера, есть риск оптимизировать не то. А что, не используя данные профайлера, этот риск как-то уменьшается?
Например, уперлись в функцию распределения памяти. Дальше что ? ее будем оптимизировать? это же данные от профайлера...
Или: для повышения производительности для надо менять асимтотику алгиритма, а мы по результатам профилирования будем оптимизировать конкретную функцию.

S>Далее, ты писал, что "обычно" легко идентифицировать проблемные места. Практика показывает, что нифига не легко. Даже при 100% понимании проекта.

Если это(проект) что-то большое, сложное и непонятное — значит нефиг лезть оптимизировать.

S>Потому, что скорость может теряться вовсе не там, где кажется. Вон недавно в веб программировании парень пытался понять, почему страничка долго грузится. Ему уж успели насоветовать советов по экономии трафика.

Значит это не 100% понимание всех потенциально проблемных мест. Имхо.

S>А оказалось, что Bottleneck — в том, как IE парсит CSS.

Во-первых: надо знать детали — при каких условиях возникла эта ситуация — сразу после написания модуля или при внесении изменений и т.д и т.п.

Во-вторых: если он спрашивал, значит предварительные замеры не принесли результата. Или что еще хуже — наверняка были попытки оптимизировать не то. Ну не верю я в то, что первое что сделал тот парень — задал вопрос на rsdn.

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

PS: Про IE & CSS — Пару лет назад слышал похожую историю в виде анекдота, правда там фигурировал объем html'a.
Re[10]: Почему преждевременная оптимизация - корень всех зол
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.08 11:57
Оценка: +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:

S>>Ну. Ты писал что а) используя данные от профайлера, есть риск оптимизировать не то. А что, не используя данные профайлера, этот риск как-то уменьшается?

ЮЖ>Например, уперлись в функцию распределения памяти. Дальше что ? ее будем оптимизировать? это же данные от профайлера...
Что значит "уперлись в функцию распределения памяти"? Что в ней мы проводим 20% времени? Или что она вызывается больше всего раз?
Ок, теперь ясно понятно, что нужно что-то с этим делать. Например, выделять память заранее блоками, чтобы снизить количество вызовов. Или ускорять ее реализацию. Всё зависит от конкретного случая.
ЮЖ>Или: для повышения производительности для надо менять асимтотику алгиритма, а мы по результатам профилирования будем оптимизировать конкретную функцию.
Ну и зачем вы будете оптимизировать конкретную функцию, если надо менять асимптотику алгоритма? Более того — как ты поймешь, что дело в асимптотике без профайлера? С профайлером всё как раз понятно — запускаем на разных объемах, смотрим различия в профилях. Статическим анализом оценить асимптотику большинства полезных алгоритмов невозможно.

ЮЖ>Если это(проект) что-то большое, сложное и непонятное — значит нефиг лезть оптимизировать.

Отлично. Дальше, в принципе, можно не общаться. Мне как-то много лет уже не удается поучаствовать в маленьких, простых и понятных проектах.

S>>Потому, что скорость может теряться вовсе не там, где кажется. Вон недавно в веб программировании парень пытался понять, почему страничка долго грузится. Ему уж успели насоветовать советов по экономии трафика.

ЮЖ>Значит это не 100% понимание всех потенциально проблемных мест. Имхо.
Ну естественно не 100%! А откуда его взять, это понимание? А? Без инструментов?
Это значит, SQL оптимизировать — не глядя в план? Web — не пользуясь фиддлером? А как тогда? Медитативно? Можно, но очень дорого.
S>>А оказалось, что Bottleneck — в том, как IE парсит CSS.
ЮЖ>Во-первых: надо знать детали — при каких условиях возникла эта ситуация — сразу после написания модуля или при внесении изменений и т.д и т.п.
Детали — важны. И результат профилирования и есть эти детали.
ЮЖ>Во-вторых: если он спрашивал, значит предварительные замеры не принесли результата.
Ну естественно, предварительные замеры были сделаны по твоей технологии: "на глазок". На сервере работает быстро, а на клиенте — медленно.
ЮЖ>Или что еще хуже — наверняка были попытки оптимизировать не то. Ну не верю я в то, что первое что сделал тот парень — задал вопрос на rsdn.
Мы не вопросы веры обсуждаем.
ЮЖ>В-третьих: Чтобы померить это сначала надо понять где мерить,
Ну как это где? Где тормозит, там и надо мерить. А ты где меришь?
ЮЖ>а не тыкать замеры где-попало: вот при этом у нас получается больше результатов — больше риск уйти в оптимизацию.
Риск уйти в оптимизацию бывает только если не пользоваться профайлером. Типа "ой, наверное асимптотика не та, давайте алгоритм поменяем". "Ой, нет, не помогло. Давайте что-нибудь еще подкрутим".
ЮЖ>PS: Про IE & CSS — Пару лет назад слышал похожую историю в виде анекдота, правда там фигурировал объем html'a.
При чем тут анекдоты? Добро пожаловать в реальный мир
Автор: tokaplan
Дата: 21.08.08
.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Почему преждевременная оптимизация - корень всех зол?
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 03.09.08 12:35
Оценка: 15 (1) +1
А>Ведь оптимизация может привести к переписыванию много чего и даже в рамках одного модуля или класса. Какой смысл в этой фразе?

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


Уже когда-то писал по этой теме, но решил и сюда вставить свои пять копеек:

"Я также знал, но забыл афоризм Хоара о том, что преждевременная оптимизация — корень всех зол в программировании".
Дональд Кнут, The Errors of TeX.

"Корректность лучше быстроты. Простота лучше сложности. Ясность лучше хитроумия. Безопасность лучше ненадежности".
Саттер, Александреску, "Стандарты программирования на С++"

"Гораздо, гораздо проще сделать корректную программу быстрой, чем быструю — корректно".
те же Саттер и Александреску

и так далее, и так далее.
Подобных цитат можно привести огромное количество. Подобные мысли встречаются в работах Мейера, Фаулера, Страуструба, банды четырех, Бека, Макконнелла, Ханта и Томаса. Общая суть которых сводиться к тому, что первое в деле разработки промышленного ПО — это качество, расширяемость, удобочитаемость кода и т.д., производительность же важна, но не в коем случае нельзя накидываться на нее с самого начала.

Но кроме всего этого, у некоторых авторов (уже приведенные выше Саттер и Александреску, а также Бентли) вводят понятие "пессимизации":
"То, что просто для вас, — просто и для кода. При прочих равных условиях, в особенности — сложности и удобочитаемости кода, ряд эффективных шаблонов проектирования и идиом кодирования должны естественным образом "стекать с кончиков ваших пальцев" и быть не сложнее в написании, чем их пессимизированные альтернативы. Это не преждевременная оптимизация, а избежание излишней пессимизации.".

При этом, в общем случае пессимизация зависит от среды, платформы, языка. Можно привести несколько примеров для C++ и .Net.

С++:
Под преждевременной писсимизацией в С++ понимается:
— передача параметров по значению, там где применима передача параметров по ссылке;
— использование постфиксной версии ++ там, где с тем же успехом можно воспользоваться префиксной версией;
— использование присваивания в конструкторах вместо списка инициализации (кстати, использование списка инициализации облегчает поддержку, в добавок к тому, что он еще и эффективнее, см. Мейерса).

Но при этом главный упор делается но то, что нужно использовать более эффективные конструкции при прочих равных условиях, т.е. более эффективные варианты не ухудшают ни дизайн, ни сложность поддержки. Часто можно встретить совет: используйте вызов функции empty() для контейнеров, вместо size() == 0, т.к. в некоторых случаях empty() будет эффективней, но кроме того эта функция лучше передает намерения программиста, она явно говорит, что размер мне не нужен, мне нужно знать пуст контейнер или нет.

Точно также Мейерс дает советы по выбору типа контейнера в зависимости от той задачи, которую необходимо решить. Если предметная область говорит, что количество данных в контейнере исчисляется тысячами и постоянно нужен поиск, то в первой итерации лучше выбрать std::set, для повышения скорости поиска. Но при этом, главное, на что делается акцент: пусть этот контейнер будет всего-лишь деталью реализации, чтобы в последствии вы могли изменить его тип, если профайлер скажет вам, что с производительностью при поиске есть какие-то проблемы.

В .Net есть свои идиомы:
— переопределение функции GetHashCode. Нужно возвращать значение, вероятность дублирования которого относительно мала. Если сделать, чтобы эта функция возвращала константу хэш-таблица выродиться в простой список;
— использование StringBuilder для динамического создания строки из множества кусков;
— использование оператора as вместо is, для определения типа объекта.

Еще раз подчеркиваю, все вышеперечисленное не является преждевременной оптимизацией, это всего-лишь разумное использование средств, которые предоставляет та или иная среда тому или иному разработчику.
Re[11]: Почему преждевременная оптимизация - корень всех зол
От: Юрий Жмеренецкий ICQ 380412032
Дата: 03.09.08 16:39
Оценка: -2 :))
Здравствуйте, Sinclair, Вы писали:

ЮЖ>>Например, уперлись в функцию распределения памяти. Дальше что ? ее будем оптимизировать? это же данные от профайлера...

S>Что значит "уперлись в функцию распределения памяти"? Что в ней мы проводим 20% времени? Или что она вызывается больше всего раз?
S>Ок, теперь ясно понятно, что нужно что-то с этим делать.
Ааа, теперь понял. Пляшем от профайлера. Надо что-то делать, а что не известно. Так же как и почему мы туда уперлись, и кто виноват...


ЮЖ>>Или: для повышения производительности для надо менять асимтотику алгиритма, а мы по результатам профилирования будем оптимизировать конкретную функцию.

S>Ну и зачем вы будете оптимизировать конкретную функцию, если надо менять асимптотику алгоритма?
Я имел ввиду "а мы, руководствуясь твоими принципами", т.е. гипотетические "мы". Я иногда себя ставлю на место собеседника и пытаюсь делать то о чем он говорит, попутно рассуждая к чему это приведет.

S>Более того — как ты поймешь, что дело в асимптотике без профайлера?

В яблочко! Вот она отправная точка. Издалека:

В соседней ветке этого-же топика я уже высказывал свою позицию по поводу проверки параметров (про бассейн в часности), иногда употребляя такие слова как "уверенность", "гарантия" и т.п. Повторюсь по пунктам, чтобы было понятно откуда растут ноги:

Любая "функциональность"(F) обладает контрактом — это значит что:
1) Контракт "превыше всего". Если написано "Не влезай — убъет" — то это и означает то что написано. Кто влез, — тот умер. Без разговоров. Кто не поял — тот умер, кто не умеет читать — тот умер. Нарушение контракта это очень серьезно. UB, форматирование винчестера, вечный цикл — все что угодно.

2) Если в контракте написано что "Если клиент(пользователь) выполнил A, то F выполнит B" — это опять же, означает то что написано. Причем F гарантирует это. Да, так бывает, если этого захотеть.

3) Самое сложное. Контракт должен покрывать все возможные случаи(в разумных пределах). Это действительно сложно. Например, как показывает практика, далеко не каждый с первого раза может написать полные постусловия для операции вставки в set.

Что мы имеем исходя из этого всего:

Никто не мешает нам включить в контракт требования по сложности (так, например, местами делает стандарт С++), да и константы в коридор поставить никто не мешает.

Ну и собственно самые сливки: если вся система построена на таких F, с четко выраженнымы контрактами(включая контракты по сложности), которым следуют все клиенты, то все точки входа/выхода(в очень широком смысле) имеют не что иное как, опять же, контракт.

S>Ну естественно не 100%! А откуда его взять, это понимание? А? Без инструментов?

А вот оно понимание(см. выше). У меня есть гарантии: контракт. Мне не нужны никакие инструменты для этого(для понимания), у меня есть контракт. На всю систему целиком.

ЮЖ>>Во-первых: надо знать детали — при каких условиях возникла эта ситуация — сразу после написания модуля или при внесении изменений и т.д и т.п.

S>Детали — важны.
Безусловно.

ЮЖ>>И результат профилирования и есть эти детали.

Это второстепенные детали.

ЮЖ>>Во-вторых: если он спрашивал, значит предварительные замеры не принесли результата.

S>Ну естественно, предварительные замеры были сделаны по твоей технологии: "на глазок".
На авторство я не претендую.

ЮЖ>>На сервере работает быстро, а на клиенте — медленно.

Значит совсем не тестировали.

ЮЖ>>Или что еще хуже — наверняка были попытки оптимизировать не то. Ну не верю я в то, что первое что сделал тот парень — задал вопрос на rsdn.

S>Мы не вопросы веры обсуждаем.
Хорошо, сократим до "наверняка были попытки оптимизировать не то". Хотя это в принципе можно назвать предположением, и ты будешь прав...

ЮЖ>>В-третьих: Чтобы померить это сначала надо понять где мерить,

S>Ну как это где?
Возвращаясь к IE: например, связка db-appserver(или что там) или webserver-client.
Тем более что такое "тормоза" формально ? да постусловия это. И там должен быть свой эквивалент assert'a(не буквально конечно) в виде performance тестов или еще как.

S>Где тормозит, там и надо мерить.

Зачем мерить там где тормозит ?

S>А ты где меришь?

в assert'ах. Опять же не буквально, но я думаю теперь понятно откуда ноги растут у отключения assert'ов в релизе ?

ЮЖ>>а не тыкать замеры где-попало: вот при этом у нас получается больше результатов — больше риск уйти в оптимизацию.

S>Риск уйти в оптимизацию бывает только если не пользоваться профайлером.
Я знаю когда возможно, то о чем ты говоришь. Это "очень bad way". Твоя альтернатива — просто "bad way". Имхо.

S>Типа "ой, наверное асимптотика не та, давайте алгоритм поменяем". "Ой, нет, не помогло. Давайте что-нибудь еще подкрутим".

Если система построена с учетом принципов, описанных выше, то этой ситуации быть не может, потому как выделенное — абсурд.
Хотя описанное возможно при рефакторинге legacy кода. При недостаточно его понимании случается "ой, нет не помогло", Все бы хорошо, но вот неожиданное "ой" говорит о некомпетентности.


ЮЖ>>PS: Про IE & CSS — Пару лет назад слышал похожую историю в виде анекдота, правда там фигурировал объем html'a.

S>При чем тут анекдоты?
При том что это оказывается популярные грабли, раз уже стали анекдотом.
Re[11]: Почему преждевременная оптимизация - корень всех зол
От: skeptik_  
Дата: 03.09.08 16:41
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Юрий Жмеренецкий, Вы писали:


S>>>Ну. Ты писал что а) используя данные от профайлера, есть риск оптимизировать не то. А что, не используя данные профайлера, этот риск как-то уменьшается?

ЮЖ>>Например, уперлись в функцию распределения памяти. Дальше что ? ее будем оптимизировать? это же данные от профайлера...
S>Что значит "уперлись в функцию распределения памяти"? Что в ней мы проводим 20% времени? Или что она вызывается больше всего раз?
S>Ок, теперь ясно понятно, что нужно что-то с этим делать. Например, выделять память заранее блоками, чтобы снизить количество вызовов. Или ускорять ее реализацию. Всё зависит от конкретного случая.
Или заменить map на vector, а присвоение на swap. Не всё так очевидно. Это реальный случай кстати.
Re[12]: Почему преждевременная оптимизация - корень всех зол
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.09.08 03:10
Оценка: +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>3) Самое сложное. Контракт должен покрывать все возможные случаи(в разумных пределах). Это действительно сложно. Например, как показывает практика, далеко не каждый с первого раза может написать полные постусловия для операции вставки в set.


ЮЖ>Что мы имеем исходя из этого всего:


ЮЖ>Никто не мешает нам включить в контракт требования по сложности (так, например, местами делает стандарт С++), да и константы в коридор поставить никто не мешает.

ЮЖ>Ну и собственно самые сливки: если вся система построена на таких F, с четко выраженнымы контрактами(включая контракты по сложности), которым следуют все клиенты, то все точки входа/выхода(в очень широком смысле) имеют не что иное как, опять же, контракт.


Юра, почитай хотя бы Кнута. Про оценки сложности алгоритмов сортировки, к примеру. Там приведены примеры ситуаций, когда из контрактов F() и G() контракт на G(F()) люди выводят годами.

А это ведь самые вырожденные случаи! Любая реальная программа неизмеримо сложнее одного маленького алгоритма сортировки.


S>>Ну естественно не 100%! А откуда его взять, это понимание? А? Без инструментов?

ЮЖ>А вот оно понимание(см. выше). У меня есть гарантии: контракт. Мне не нужны никакие инструменты для этого(для понимания), у меня есть контракт. На всю систему целиком.
В общем, я понял: ты работаешь только с примитивными вычислительными программами, где 100% точные требования к софту известны за пять лет до начала разработки и утверждены комитетами. При этом размер задачи настолько незначителен, что для ее решения достаточно одного программиста.

Ему не нужно отлаживать программу — за него ошибки устранил Контракт(тм).
Ему не нужно оптимизировать программу — за него оптимальность гарантировал Контракт(тм).
Если его не устраивает производительность — он смотрит в табличку Контрактов(тм) и меняет одну функцию на другую, с таким же Контрактом по поведению, но более удачным по сложности. Впрочем, о чем это я? Если это суперпрограммист, то он никогда не выберет функцию с неудачным контрактом.

В общем, фантастические мечты — это не ко мне. Ты лучше про это Лукьяненко вот напиши.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Почему преждевременная оптимизация - корень всех зол
От: Юрий Жмеренецкий ICQ 380412032
Дата: 04.09.08 07:53
Оценка:
Здравствуйте, Sinclair, Вы писали:
...
S>Юра, почитай хотя бы Кнута. Про оценки сложности алгоритмов сортировки, к примеру.
Тише, Антон, тише. я тоже могу послать почитать.

S>Там приведены примеры ситуаций, когда из контрактов F() и G() контракт на G(F()) люди выводят годами.

Это всего лишь подтверждает тот факт, что из всех правил бывают исключения. У нас кое-какие(где-то больше, где-то меньше) контракты и свойства автоматически выводятся. Дальше что ? Объявим ересью ? Геделя вспомним ?

S>А это ведь самые вырожденные случаи! Любая реальная программа неизмеримо сложнее одного маленького алгоритма сортировки.

Они вырожденные не в этом смысле. Есть проблемы, но они совершенно другого рода.

S>>>Ну естественно не 100%! А откуда его взять, это понимание? А? Без инструментов?

ЮЖ>>А вот оно понимание(см. выше). У меня есть гарантии: контракт. Мне не нужны никакие инструменты для этого(для понимания), у меня есть контракт. На всю систему целиком.
S>В общем, я понял:
Нет, — придумал. т.к. не можешь понять откуда у менять есть контракт на всю систему (это между прочим не 100% гарантия работоспособности или отсутствия ошибок). это нечто другое.

S>где 100% точные требования к софту известны за пять лет до начала разработки и утверждены комитетами.

По крайней мере одно требование всегда известно до начала разработки. Цена ошибки.

S>При этом размер задачи настолько незначителен, что для ее решения достаточно одного программиста.

Угу, со своими компиляторами(не шарп, и не С++), с разработкой одного функционала несколькими независимыми группами(казалось бы, зачем?), с тестированием по 4-8 месяцев, которое даже остановить-то проблематично.

S>Ему не нужно отлаживать программу — за него ошибки устранил Контракт(тм).

S>Ему не нужно оптимизировать программу — за него оптимальность гарантировал Контракт(тм).
S>Если его не устраивает производительность — он смотрит в табличку Контрактов(тм) и меняет одну функцию на другую, с таким же Контрактом по поведению, но более удачным по сложности. Впрочем, о чем это я? Если это суперпрограммист, то он никогда не выберет функцию с неудачным контрактом.
S>В общем, фантастические мечты — это не ко мне.

Аха, давай спустимся на землю. Чего мы имеем:
* Самый главный(или один из них) интрумент — оптимизатор. Мереем все подряд ибо может тормозить все что угодно, попутно мотивируя бесконтрольной "большой системой", которую мы не знаем, но все равно лезем в нее.
* Ассерты оставляем в релизе(хотя это уже не ассерты, а черти что).
* Не доверяем своему коду до такой степени, что в ужасе начинаем проверять все параметры всех функций. Кстати, причина — из-за того что внешие данные могут приити откуда угодно. Потому что:
* Контрактов естественно нет(даже если есть — то с очень странными целями).
* добавить по вкусу.
Реальность ? да. Наелся я такого, спасибо.

S>ты работаешь только с примитивными вычислительными программами

Сразу бы и спрашивал сколько сантиметров. Хотя я сюда не за этим пришел. "Дальше, в принципе, можно не общаться" (c)
Re[14]: Почему преждевременная оптимизация - корень всех зол
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.09.08 08:32
Оценка: +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Это всего лишь подтверждает тот факт, что из всех правил бывают исключения. У нас кое-какие(где-то больше, где-то меньше) контракты и свойства автоматически выводятся. Дальше что ? Объявим ересью ? Геделя вспомним ?

Объявим бесполезными с практической точки зрения.
Поясняю на пальцах: вот есть у нас IM клиент. Например, Office Communicator. Довольно сложная софтина, с запутанными call stack, тащит за собой кучу библиотек, для которых никаких контрактов сложности дать не удается. Ну вот какой, к примеру, контракт может быть у парсера XML? В каких терминах он будет выражен?
Ок, хорошо, давайте попробуем обконтрактить передачу данных по TCP/IP. Да хотя бы чтение из файлухи заведомо не дает никаких гарантий.
И что мы теперь будем с ним делать, с таким софтом? Искать программиста, который "реально разбирается во всех тонкостях" всего подряд?
А остальным даже подойти не дадим? Спасибо, до свидания.

ЮЖ>Они вырожденные не в этом смысле. Есть проблемы, но они совершенно другого рода.

Какого рода?

S>>При этом размер задачи настолько незначителен, что для ее решения достаточно одного программиста.

ЮЖ>Угу, со своими компиляторами(не шарп, и не С++), с разработкой одного функционала несколькими независимыми группами(казалось бы, зачем?), с тестированием по 4-8 месяцев, которое даже остановить-то проблематично.
А, ну так надо было с самого начала и говорить, что речь идет о нишевой разработке. На специальном языке, в специальных условиях.
А остальным что делать?

ЮЖ>Аха, давай спустимся на землю. Чего мы имеем:

ЮЖ>* Самый главный(или один из них) интрумент — оптимизатор. Мереем все подряд ибо может тормозить все что угодно, попутно мотивируя бесконтрольной "большой системой", которую мы не знаем, но все равно лезем в нее.
А что такое "оптимизатор"? У тебя какие-то представления об оптимизации софта совершенно особые, не связанные с реальностью. Юра, поясню опять же, на пальцах: оптимизатор — это человек.
И естественно он не знает "систему". Потому, что сейчас невозможно уже знать "систему", она за рамки головы вылезает.
Далее, этот человек не "мереет всё подряд". Он берет некие сценарии использования, и прогоняет через профайлер. После чего получает информацию о том, как устроена производительность софта. Ему не страшно отсутствие либо наличие контрактов; ему не страшно отсутствие проверки контрактов компилятором и риск получить вранье в контракте. Ему не нужно знать наизусть систему от и до. Он видит реальную картину поведения софта в реальном окружении.
После этого у него обычно появляется понимание, куда нужно копать. В софт вносятся изменения, и цикл тестирования повторяется. Иногда приходится проводить дополнительные измерения, потому что начальные не дали нужных данных. Таким образом, безо всяких предварительных условий мы получаем нужный результат.

Остальные домыслы я поскипаю. С ними, опять же, не ко мне.

S>>ты работаешь только с примитивными вычислительными программами

ЮЖ>Сразу бы и спрашивал сколько сантиметров.
Дело не в сантиметрах. Дело в применимости подходов. Ты вот почему-то всё время делаешь таинственное лицо, и критикуешь зарекомендовавшие себя паттерны. А взамен — только лозунги и абстрактные рассуждения о каких=то контрактах, безо всяких уточнений.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Почему преждевременная оптимизация - корень всех зол
От: Юрий Жмеренецкий ICQ 380412032
Дата: 04.09.08 10:51
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Юрий Жмеренецкий, Вы писали:


ЮЖ>>Это всего лишь подтверждает тот факт, что из всех правил бывают исключения. У нас кое-какие(где-то больше, где-то меньше) контракты и свойства автоматически выводятся. Дальше что ? Объявим ересью ? Геделя вспомним ?

S>Объявим бесполезными с практической точки зрения.
S>Поясняю на пальцах: вот есть у нас IM клиент. Например, Office Communicator. Довольно сложная софтина, с запутанными call stack, тащит за собой кучу библиотек, для которых никаких контрактов сложности дать не удается. Ну вот какой, к примеру, контракт может быть у парсера XML? В каких терминах он будет выражен?
S>Ок, хорошо, давайте попробуем обконтрактить передачу данных по TCP/IP. Да хотя бы чтение из файлухи заведомо не дает никаких гарантий.

Такие описанные места называются "vulnerability window" — то о чем у нас нет достоверных данных, документации и т.п. и им уделяется максимальное внимание. Так как по определению там можно нарватся на просады производительности, то все эти места тестируются(перед использованием) в различных режимах, собирается(и документируется) статистика и делается вывод о пригодности использования в каких-то рамках. Это относится не только к производительности: все данные, входящие из таких "черных дыр" тщательно проверяются(типа как проверяется user input). и только потом поступают в систему.

Этот подход не может давать гарантированные 100% результаты, но очень сильно снижает недетерминированность системы в целом. Кроме того эти места действуют на всех как красная тряпка на быка: про них все знают, и если возникают какие либо подозрения — то они проверяются в первую очередь.

ЮЖ>>Они вырожденные не в этом смысле. Есть проблемы, но они совершенно другого рода.

S>Какого рода?

Если у нас имеется контракт, который описывает все возможные исходы, то иногда, даже несмотря на это, — нет уверенности в правильности результата. Начиная от невозможности протестировать: не с чем сравнивать например, или тестовые прогоны очень дорогие, или наличие скрытых взаимодействий. и т.п.

Кое-что из этого решает N-version programming, но это совсем крайность: делаем N реализаций одного алгоритма, запускаем, и... попадаем: а что делать с результатами?...

S>>>При этом размер задачи настолько незначителен, что для ее решения достаточно одного программиста.

ЮЖ>>Угу, со своими компиляторами(не шарп, и не С++), с разработкой одного функционала несколькими независимыми группами(казалось бы, зачем?), с тестированием по 4-8 месяцев, которое даже остановить-то проблематично.
S>А, ну так надо было с самого начала и говорить, что речь идет о нишевой разработке. На специальном языке, в специальных условиях.
S>А остальным что делать?

Представить что любая программа должна работать в режиме 24x7. Вообще любая.

Другой вариант(как бы нелепо это не звучало) — представить что ошибка в любой программе приведет к человеческим жертвам. После этого даже просто отношение меняется.

S>А что такое "оптимизатор"?

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

S>оптимизатор — это человек.

Ок.

S>И естественно он не знает "систему". Потому, что сейчас невозможно уже знать "систему", она за рамки головы вылезает.

S>Далее, этот человек не "мереет всё подряд". Он берет некие сценарии использования, и прогоняет через профайлер.
S>После чего получает информацию о том, как устроена производительность софта. Ему не страшно отсутствие либо наличие контрактов;
Наличие не должно быть страшным =) этим надо пользоваться.

S>ему не страшно отсутствие проверки контрактов компилятором и риск получить вранье в контракте. Ему не нужно знать наизусть систему от и до. Он видит реальную картину поведения софта в реальном окружении.

S>После этого у него обычно появляется понимание, куда нужно копать.

Вот кстати, зачем обязательно в реально окружении? Почему нельзя заранее протестировать изолированные части? Что мешает? Смоделировать низкий пропускной канал, например, не проблема, тучу клиентских запросов тоже. Неужели система в "целом" начинает жить непредсказуемо?

И еще: cколько времени понадобилось вышеописанному оптимизатору? Для него в такой ситуации — тормоза могут быть где угодно(в пределах сценариев использования), система ведь большая.

В моем случае — тормоза гдето в местах обозначенных красной тряпкой. А их количство стремятся минимизировать.

S>Дело в применимости подходов.

Да тут все просто. Правило треугольника(или как там), — Время, Стоимость, Качество. Фиксировать можно две величины. Для проектов из "реального мира" зафиксированы первые две. Мне больше импонирует ситуация, когда первым компонентом является качество, а вторым может быть хоть что.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.