Все мы знаем, что преждевременная оптимизация является корнем всего зла, потому что оно приводит к нечитаемому / не поддерживаемому коду. Еще хуже пессимизация, когда кто-то реализует «оптимизацию», потому что он думает, что она будет быстрее, но в конечном итоге она будет медленнее, а также будет содержать ошибки, не поддерживаться и т. Д. Какой самый нелепый пример этого вы видели ?
performance
optimization
dsimcha
источник
источник
Ответы:
В старом проекте мы унаследовали некоторые (в остальном отличные) программисты встраиваемых систем, которые имели большой опыт работы с Z-8000.
Нашей новой средой был 32-битный Sparc Solaris.
Один из парней пошел и заменил все целые числа на шорты, чтобы ускорить наш код, поскольку захват 16 битов из оперативной памяти был быстрее, чем захват 32 битов.
Мне пришлось написать демонстрационную программу, чтобы показать, что захват 32-битных значений в 32-битной системе быстрее, чем захват 16-битных значений, и объяснить, что для получения 16-битного значения процессор должен был иметь ширину 32 бита. доступ к памяти, а затем замаскировать или сдвинуть биты, не необходимые для 16-битного значения.
источник
Я думаю, что фраза «преждевременная оптимизация - корень всего зла» - это путь, путь использованный. Для многих проектов это стало поводом не принимать во внимание производительность до поздней стадии проекта.
Эта фраза часто является опорой для людей, чтобы избежать работы. Я вижу эту фразу, когда люди действительно должны сказать: «Ну и дела, мы действительно не думали об этом заранее, и у нас нет времени, чтобы разобраться с этим сейчас».
Я видел гораздо больше «нелепых» примеров глупых проблем с производительностью, чем примеров проблем, вызванных «пессимизацией»
Я думаю, что лучше сказать следующее: «Оптимизация без измерения и понимания вовсе не является оптимизацией - это просто случайное изменение».
Хорошая производительность требует значительных затрат времени - чаще всего для разработки самой функции или компонента.
источник
Базы данных являются пессимизацией игровых площадок.
Избранное включает в себя:
Это с моей головы.
источник
Я думаю, что нет абсолютного правила: некоторые вещи лучше всего оптимизировать заранее, а некоторые нет.
Например, я работал в компании, где мы получали пакеты данных со спутников. Каждый пакет стоит больших денег, поэтому все данные были высоко оптимизированы (т.е. упакованы). Например, широта / долгота были отправлены не как абсолютные значения (с плавающей точкой), а как смещения относительно «северо-западного» угла «текущей» зоны. Нам пришлось распаковать все данные, прежде чем они могли быть использованы. Но я думаю, что это не пессимизация, это интеллектуальная оптимизация для снижения затрат на связь.
С другой стороны, наши разработчики программного обеспечения решили, что распакованные данные должны быть отформатированы в очень читаемый XML-документ и сохранены в нашей базе данных как таковой (в отличие от хранения каждого поля в соответствующем столбце). Их идея заключалась в том, что «XML - это будущее», «дисковое пространство дешевое» и «процессор дешевый», поэтому не нужно было ничего оптимизировать. В результате наши 16-байтовые пакеты были превращены в документы размером 2 КБ, хранящиеся в одном столбце, и даже для простых запросов нам пришлось загружать мегабайты документов XML в память! Мы получали более 50 пакетов в секунду, поэтому вы можете себе представить, насколько ужасной стала производительность (кстати, компания обанкротилась).
Итак, еще раз, нет абсолютного правила. Да, иногда слишком ранняя оптимизация является ошибкой. Но иногда девиз «процессор / дисковое пространство / память дешев» - это настоящий корень всего зла.
источник
О, Господи, я думаю, что видел их всех. Чаще всего это попытка исправить проблемы с производительностью кем-то, кто слишком ленив, чтобы выяснить причину этих проблем с производительностью или даже выяснить, действительно ли существует проблема с производительностью. Во многих из этих случаев мне интересно, не тот ли это случай, когда человек хочет попробовать какую-то особую технологию и отчаянно ищет гвоздь, который подходит для их нового блестящего молотка.
Вот недавний пример:
Архитектор данных приходит ко мне с тщательно продуманным предложением по вертикальному разделению таблицы ключей в довольно большом и сложном приложении. Он хочет знать, какой тип усилий по разработке понадобится для адаптации к изменениям. Разговор шел так:
Я: Почему вы рассматриваете это? Какую проблему вы пытаетесь решить?
Он: Таблица X слишком широка, мы разбиваем ее по соображениям производительности.
Я: Что заставляет вас думать, что оно слишком широкое?
Он: Консультант сказал, что в одной таблице слишком много столбцов.
Я: И это влияет на производительность?
Ему: Да, пользователи сообщают о периодических замедлениях в модуле XYZ приложения.
Меня: Откуда вы знаете, что ширина таблицы является источником проблемы?
Ему: Это таблица ключей, используемая модулем XYZ, и она похожа на 200 столбцов. Это должно быть проблемой.
Я (Объяснение): Но модуль XYZ, в частности, использует большинство столбцов в этой таблице, и столбцы, которые он использует, непредсказуемы, поскольку пользователь настраивает приложение для отображения данных, которые он хочет отобразить из этой таблицы. Вполне вероятно, что в 95% случаев мы все равно будем объединять все столы вместе, что ухудшит производительность.
Ему: Консультант сказал, что он слишком широкий, и нам нужно его изменить.
Меня: Кто этот консультант? Я не знал, что мы наняли консультанта, и они вообще не разговаривали с командой разработчиков.
Ему: Ну, мы еще не наняли их. Это часть предложения, которое они предложили, но они настаивали на том, что нам нужно реорганизовать эту базу данных.
Меня: Ага. Поэтому консультант, который продает услуги по перепроектированию базы данных, считает, что нам нужно перепроектировать базу данных ....
Разговор продолжался и продолжался вот так. После этого я еще раз взглянул на данную таблицу и определил, что ее можно сузить с помощью некоторой простой нормализации без необходимости использования экзотических стратегий разбиения. Это, конечно, оказалось спорным вопросом, как только я исследовал проблемы с производительностью (ранее не сообщавшиеся) и выявил их по двум факторам:
Конечно, архитектор по-прежнему настаивает на вертикальном разделении стола, опираясь на «слишком широкую» мета-проблему. Он даже поддержал свое дело, получив предложение от другого консультанта по базам данных, который смог определить, что нам нужны серьезные изменения в базе данных, не глядя на приложение и не проводя анализ производительности.
источник
Я видел людей, использующих alphadrive-7 для полной инкубации CHX-LT. Это необычная практика. Более распространенной практикой является инициализация ZT-преобразователя, чтобы уменьшить буферизацию (из-за большей устойчивости к перегрузке) и создать байтовую символику в стиле Java.
Абсолютно пессимистично!
источник
Признаюсь, ничего страшного, но я поймал людей, использующих StringBuffer для объединения строк вне цикла в Java. Это было что-то простое, как поворот
в
Раньше было довольно распространенной практикой использовать технику в цикле, потому что она была заметно быстрее. Дело в том, что StringBuffer синхронизирован, так что на самом деле есть дополнительные издержки, если вы объединяете только несколько строк. (Не говоря уже о том, что в этой шкале разница абсолютно тривиальна.) Два других момента об этой практике:
источник
Однажды я увидел базу данных MSSQL, в которой использовалась таблица «Root». Корневая таблица имела четыре столбца: GUID (уникальный идентификатор), ID (int), LastModDate (datetime) и CreateDate (datetime). Все таблицы в базе данных были Внешним Ключом к Корневой таблице. Всякий раз, когда новая строка была создана в любом таблице в БД , вам приходилось использовать пару хранимых процедур для вставки записи в корневую таблицу, прежде чем вы могли бы перейти к фактической таблице, которая вам нужна (вместо того, чтобы база данных выполняла работу для Вы с несколькими триггерами простых триггеров).
Это создало беспорядок бесполезных подслушиваний и головных болей, требовало от всего, что написано на нем, использовать sprocs (и исключало мои надежды представить LINQ для компании. Это было возможно, но просто не стоило головной боли), и завершить это не стало ' даже не выполнить то, что предполагалось.
Разработчик, выбравший этот путь, защитил его, предполагая, что это сэкономило тонны пространства, потому что мы не использовали Guids для самих таблиц (но ... не генерируется ли GUID в корневой таблице для каждой строки, которую мы создаем?) каким-то образом улучшил производительность и сделал «легким» аудит изменений в базе данных.
О, и диаграмма базы данных выглядела как паук-мутант из ада.
источник
Как насчет POBI - пессимизация, очевидно, по намерению?
Моя коллега в 90-х устала от того, что генеральный директор пинал ее в задницу только потому, что генеральный директор провел первый день каждого выпуска программного обеспечения ERP (пользовательского) с поиском проблем с производительностью в новых функциях. Даже если новые функциональные возможности сокращали гигабайты и делали невозможное возможным, он всегда находил какие-то детали или даже, казалось бы, серьезную проблему, чтобы скулить. Он считал, что знает много о программировании и получил свои удары ногами программиста.
Из-за некомпетентного характера критики (он был генеральным директором, а не ИТ-специалистом), моему коллеге так и не удалось сделать это правильно. Если у вас нет проблемы с производительностью, вы не можете ее устранить ...
Вплоть до одного выпуска он поместил много вызовов функции Delay (200) (это был Delphi) в новый код. Прошло всего 20 минут после начала работы, и ему было приказано явиться в офис генерального директора, чтобы лично принести ему запоздалые оскорбления.
Единственным необычным моментом было то, что мои коллеги молчали, когда он возвращался, улыбался, шутил, выходил на BigMac или два, пока он обычно пинал столы, разглагольствовал о генеральном директоре и компании, а остаток дня провел до смерти ,
Естественно, мой коллега теперь отдыхал в течение одного или двух дней за его столом, улучшая свои навыки прицеливания в Quake - затем на второй или третий день он удалил вызовы задержки, восстановил и выпустил «экстренный патч», о котором он распространял слово что он потратил 2 дня и 1 ночь, чтобы исправить дыры в производительности.
Это был первый (и единственный) раз, когда злой генеральный директор сказал "отличная работа!" Для него. Это все, что имеет значение, верно?
Это было настоящее ПОБИ.
Но это также своего рода оптимизация социального процесса, так что все в порядке.
Думаю.
источник
«База данных независимости». Это означало отсутствие хранимых процедур, триггеров и т. Д. - даже никаких внешних ключей.
источник
Лучшее использование StringBuilder, которое я когда-либо видел.
источник
Использование регулярного выражения для разделения строки, когда достаточно простого string.split
источник
Очень поздно к этой теме я знаю, но я видел это недавно:
Знаете, на случай, если логическое значение имеет некоторые дополнительные значения ...
источник
Худший пример, который я могу вспомнить, - это внутренняя база данных в моей компании, содержащая информацию обо всех сотрудниках. Он получает еженедельное обновление от HR и имеет веб-сервис ASP.NET на вершине. Многие другие приложения используют веб-сервис для заполнения таких вещей, как поля поиска / раскрывающегося списка.
Пессимизм заключается в том, что разработчик считал, что повторные вызовы веб-службы будут слишком медленными для выполнения повторных запросов SQL. И что он сделал? Событие запуска приложения считывает всю базу данных и преобразует все это в объекты в памяти, которые хранятся неопределенно долго, пока пул приложений не будет перезагружен. Этот код был настолько медленным, что его загрузка заняла бы менее 15 минут у менее чем 2000 сотрудников. Если вы случайно переработали пул приложений в течение дня, это может занять 30 минут или более, поскольку каждый запрос веб-службы будет запускать несколько одновременных перезагрузок. По этой причине новые сотрудники не будут появляться в базе данных в первый день, когда была создана их учетная запись, и, следовательно, не смогут получить доступ к большинству внутренних приложений в первые пару дней, трясясь пальцами.
Второй уровень пессимизма заключается в том, что менеджер по разработке не хочет прикасаться к нему, опасаясь взлома зависимых приложений, но, тем не менее, у нас по-прежнему случаются периодические сбои в работе критически важных приложений в масштабах всей компании из-за плохого дизайна такого простого компонента.
источник
Кажется, никто не упомянул сортировку, так что я буду.
Несколько раз я обнаруживал, что кто-то создал ручную сортировку пузырей, потому что ситуация «не требует» вызова алгоритма быстрой сортировки, который уже существует. Разработчик остался доволен, когда их пузырьковая сортировка ручной работы достаточно хорошо работала с десятью рядами данных, которые они используют для тестирования. После того, как заказчик добавил пару тысяч строк, все закончилось не очень хорошо.
источник
Однажды я работал над приложением, которое было полно кода, подобного этому:
Просто удалите
found
, вернувшисьnull
в конце, и изменив шестую строку на:Удвоил производительность приложения.
источник
Однажды мне пришлось попытаться изменить код, который включал эти драгоценные камни в класс констант
Каждый из них использовался несколько раз в остальной части приложения для различных целей. COMMA_DELIMINATOR замусорил код с более чем 200 использованиями в 8 различных пакетах.
источник
Большое все время номер один, с которым я сталкиваюсь снова и снова в собственных программах:
Не использовать функции СУБД по причинам «переносимости», потому что «мы можем захотеть переключиться на другого поставщика позже».
Читай по губам. Для любой внутренней работы: ЭТОГО НЕ БУДЕТ!
источник
У меня был сотрудник, который пытался перехитрить наш оптимизатор компилятора Си и регулярно переписывал код, который мог прочитать только он. Одним из его любимых приемов было изменение читабельного метода, например (составление кода):
в это:
Таким образом, первая строка
return
некодируемого метода станет « », а вся другая логика будет заменена глубоко вложенными троичными выражениями. Когда вы пытались спорить о том, как это было недопустимо, он указывал на тот факт, что результат сборки его метода был на три или четыре инструкции по сборке короче. Это не обязательно любой быстрее , но он всегда был крошечный немного короче. Это была встроенная система, в которой время от времени имело значение использование памяти, но можно было сделать гораздо более простые оптимизации, чем те, которые сделали бы код читабельным.Затем, после этого, по какой-то причине он решил, что
ptr->structElement
это слишком нечитаемо, поэтому он начал менять все это(*ptr).structElement
на теорию, что это было более читабельно и быстрее.Превращение читаемого кода в нечитаемый код для улучшения не более чем на 1%, а иногда и на самом деле более медленный код.
источник
if
. Упорство на высказываниях над выражениями на языке C является культурной / религиозной догмой, а не какой-либо объективной практикой. (Лучшее указание: если вложенная троичнаяif
if
в функции и заменить его троичным. Это хорошо, и часто более читабельно. Я говорю о замене целого 30-строчного метода одним оператором возврата и вложенными троичными. Никто не думал, что новый код был более читабельным, но один разработчик думал, что это быстрее.На одном из моих первых заданий в качестве полноправного разработчика я занялся проектом программы, которая страдала от проблем масштабирования. Он работал бы достаточно хорошо на небольших наборах данных, но полностью потерпел бы крах при наличии большого количества данных.
Пока я копался, я обнаружил, что оригинальный программист стремился ускорить процесс, распараллеливая анализ - запуская новый поток для каждого дополнительного источника данных. Однако он допустил ошибку в том, что для всех потоков требовался общий ресурс, на котором они находились в тупике. Конечно, все преимущества параллелизма исчезли. Более того, большинство систем рухнуло, чтобы запустить более 100 потоков только для блокировки всех, кроме одной. Моя мощная девайс-машина была исключением из-за того, что она прошла через набор из 150 источников примерно за 6 часов.
Чтобы исправить это, я удалил многопоточные компоненты и очистил ввод-вывод. Без каких-либо других изменений время выполнения набора данных из 150 источников на моей машине упало ниже 10 минут, а на средней машине компании - от бесконечности до менее получаса.
источник
Я полагаю, я мог бы предложить этот драгоценный камень:
Так как квадратный корень был рассчитан в очень чувствительном месте, я получил задачу найти способ сделать его быстрее. Этот небольшой рефакторинг сократил время выполнения на треть (для комбинации используемого оборудования и компилятора, YMMV):
Конечно, есть и более быстрые, и лучшие способы сделать это, но я думаю, что это довольно хороший пример пессимизации.
Изменить: если подумать, развернутый цикл был на самом деле также аккуратная пессимизация. Пройдя через контроль версий, я также могу представить второй этап рефакторинга, который показал себя даже лучше, чем выше:
Это точно такой же алгоритм, хотя и немного другая реализация, поэтому я полагаю, что он подходит.
источник
isqrt()
вычисляетfloor(sqrt())
, но, почему этот код работает?Это может быть на более высоком уровне, чем то, что вы делали, но исправление (если вам позволено) также включает больший уровень боли:
Настаивайте на том, чтобы вручную запустить Диспетчер объектных отношений / Уровень доступа к данным вместо использования одной из установленных, протестированных, зрелых библиотек (даже после того, как они были вам указаны).
источник
Все ограничения внешнего ключа были удалены из базы данных, потому что в противном случае было бы так много ошибок.
источник
Это не совсем подходит к вопросу, но я все равно упомяну об этом предостерегающую историю. Я работал над распределенным приложением, которое работало медленно, и прилетел в округ Колумбия, чтобы принять участие в совещании, в первую очередь направленном на решение проблемы. Руководитель проекта начал обрисовывать реструктуризацию, направленную на устранение задержки. Я вызвался, что в выходные я провел некоторые измерения, которые изолировали узкое место от одного метода. Оказалось, что при локальном поиске отсутствовала запись, из-за которой приложению приходилось переходить на удаленный сервер при каждой транзакции. Добавив запись обратно в локальное хранилище, задержка была устранена - проблема решена. Обратите внимание, что перестройка не решит проблему.
источник
Перед КАЖДОЙ операцией javascript проверяется, существует ли объект, с которым вы работаете.
Моя проблема с этим типом кода - никого не волнует, что если его не существует? Просто ничего не делать? Не дать отзыв пользователю?
Я согласен, что
Object expected
ошибки раздражают, но это не лучшее решение для этого.источник
Как насчет ЯГНИ, экстремизм. Это форма преждевременной пессимизации. Кажется, что каждый раз, когда вы применяете YAGNI, вам это в конечном итоге понадобится, что в 10 раз увеличит ваши усилия по добавлению, чем если бы вы добавили его в начале. Если вы создаете успешную программу, то, скорее всего, вам это нужно. Если вы привыкли создавать программы, жизнь которых заканчивается быстро, продолжайте практиковать ЯГНИ, потому что тогда я полагаю, ЯГНИ.
источник
Не совсем преждевременная оптимизация - но, безусловно, ошибочная - это было прочитано на сайте BBC, из статьи, обсуждающей Windows 7.
Я еще не пробовал Windows 7, поэтому могу ошибаться, но готов поспорить, что есть и другие проблемы, которые важнее, чем время, необходимое для завершения работы. В конце концов, когда я вижу сообщение «Завершение работы Windows», монитор выключается, и я ухожу - как мне помогают эти 400 миллисекунд?
источник
Кто-то в моем отделе однажды написал строковый класс. Интерфейс как
CString
, но без зависимости от Windows.Одна «оптимизация», которую они сделали, состояла в том, чтобы не выделять больше памяти, чем необходимо. По-видимому, не понимая, что классы причин, такие как
std::string
действительно, выделяют избыточную память так, что последовательность+=
операций может выполняться за O (n) времени.Вместо этого каждый отдельный
+=
вызов вызывал перераспределение, которое превращало повторяющиеся добавления в алгоритм Шлеймеля-живописца O (n²) .источник
Моему бывшему сотруднику (собственно говоря ) было поручено создать новый модуль для нашей Java ERP, который должен был собирать и анализировать данные клиентов (розничная торговля). Он решил разделить поле КАЖДЫЙ календарь / дата / время на его компоненты (секунды, минуты, часы, день, месяц, год, день недели, биместер, триместр (!)), Потому что «как еще мне запросить« каждый понедельник »?»
источник
Никому не в обиду, но я просто оценил задание (java), в котором было это
источник