По причине, которая в значительной степени не имеет значения, я установил Delphi 7 еще раз за такое долгое время. Я должен сказать, я был полностью потрясен - таким образом, я не был довольно долгое время. Это не то, как я помню вещи вообще. Установка заняла около 30 секунд. Запуск занял 2 секунды, и он был сразу же применим. Я могу нажать «Выполнить» через секунду после его запуска, и менее чем через секунду пустая программа уже видна и работает. Ура для компьютеров становится намного быстрее!
Но причина, по которой я так поражен, заключается в том, что обычно я использую Visual Studio 2010, который совсем не чувствует себя так быстро. Конечно, Delphi 7 является гораздо меньше , чем система Visual Studio 2010, но у него есть внешний вид того , чтобы все действительно необходимые вещи там: палитра управления, конструктор форм, редактор кода с кодом завершения. Я понимаю, что язык может быть проще, а завершение кода может быть гораздо менее мощным, и IDE может быть не настолько расширяемым и многофункциональным, но все же: я не понимаю, как (т.е. через какой механизм) Множество дополнительных функций (которые я, возможно, еще даже не включил) заставляют систему, подобную Visual Studio, всегда чувствовать себя вялой по сравнению.
Я хотел бы спросить людей, имеющих опыт работы с системами в масштабе Visual Studio: что делает их медленными? Являются ли слои за слоями абстракций, необходимые для сохранения кодовой базы в пределах возможностей человеческого понимания? Это огромное количество кода, которое нужно пройти? Является ли это современной тенденцией к подходам, экономящим время программистов, за (ошеломляюще огромные) расходы в отделе тактов / использования памяти?
источник
Ответы:
Архитектурная космонавтика
Visual Studio 2010 основана на Windows Presentation Foundation. Взгляните на класс Button для WPF. Это 9-й ребенок из базового класса. Он содержит около 5 страниц свойств, методов и событий. За кулисами у него есть еще пять страниц определений стилей, которые описывают его красиво закругленные углы и тонкие анимационные переходы, когда курсор мыши перемещается над ним. Это все для чего-то, что в основном отображает некоторый текст или изображение и производит событие щелчка, когда он обнаруживает нажатие кнопки мыши.
Остановите программу, подобную Visual Studio, в любой случайной точке. Посмотрите на трассировку стека. Скорее всего, очень хорошо, что вы на 20 уровней вглубь стека вызовов и что пять DLL были загружены, чтобы туда попасть.
Теперь сравните эти две вещи с Delphi. Бьюсь об заклад, вы обнаружите, что кнопка Delphi имеет только 20 свойств, методов и событий. Могу поспорить, что Delphi IDE имеет трассировку стека глубиной всего 5-7 уровней. Потому что, когда компьютеры работали медленнее, вы просто не могли взять на себя накладные расходы Visual Studio 2010 без IDE, затрачиваемого на запуск 40 минут :-)
Один лучше другого? Ну, я обычно могу сказать программе Delphi, когда она загружается, потому что она выглядит плоской, цвета приглушены (возможно, 8-битные?), И нет тонкого затенения или анимации. Я просто чувствую себя дешевым в эти дни. Дешево, но быстро.
Нам лучше? Это вопрос к философам, а не к кодерам.
источник
Я думаю, что вы догадались, что некоторые из них, но я хотел бы предложить то, что я считаю самым важным фактором, работая над достаточно большой базой кода (не уверен, что он такой же большой, как Visual Studio - в миллионах строк кода) категория и около тысячи плагинов) в течение примерно 10 лет и наблюдения явления происходят.
Это также немного менее спорным, так как он не входит в API, или функции языка или что-нибудь подобное. Это относится к «затратам», которые могут породить дебаты, а не «расходы», и я хочу сосредоточиться на «расходах».
Свободная координация и наследие
Я заметил, что слабая координация и долгое наследие приводят к большому количеству накопленных отходов.
Например, я нашел около ста ускоряющих структур в этой кодовой базе, многие из которых избыточны.
У нас было бы как дерево KD для ускорения одного физического движка, другого для нового физического движка, который часто работал параллельно со старым, у нас были бы десятки реализаций октодеревьев для различных алгоритмов сетки, другое дерево KD для рендеринга , подбор и т. д. и т. д. и т. д. Это все большие, громоздкие древовидные структуры, используемые для ускорения поиска. Каждый из них может занимать сотни мегабайт в гигабайтах памяти для ввода очень среднего размера. Они не всегда создавались и использовались постоянно, но в любой момент времени 4 или 5 из них могли бы быть в памяти одновременно.
Теперь все они хранили одни и те же данные, чтобы ускорить их поиск. Вы можете представить ее как аналогичную старую аналогичную базу данных, которая хранит все свои поля в 20 различных избыточных картах / словарях / деревьях B + одновременно, одинаково организованных по одним и тем же ключам, и постоянно ищет их все. Теперь мы берем в 20 раз больше памяти и обработки.
Кроме того, из-за избыточности у нас мало времени на оптимизацию любого из них с помощью стоимости обслуживания, которая идет с этим, и даже если бы мы это сделали, это дало бы только 5% эффекта, который в идеале был бы.
Что вызывает это явление? Слабая координация была причиной номер один, которую я видел. Многие члены команды часто работают в своих изолированных экосистемах, разрабатывая или используя сторонние структуры данных, но не используя те же структуры, которые использовали другие члены команды, даже если они были откровенно вопиющими дубликатами тех же проблем.
Что заставляет это явление сохраняться? Наследие и совместимость были главной причиной, которую я видел. Поскольку мы уже заплатили за реализацию этих структур данных, а большие объемы кода зависели от этих решений, зачастую было слишком рискованно пытаться объединить их с меньшим количеством структур данных. Несмотря на то, что многие из этих структур данных были концептуально избыточными, они не всегда были похожи друг на друга в своих интерфейсах. Поэтому замена их была бы большим, рискованным изменением, а не просто позволила бы им потреблять память и время обработки.
Эффективность памяти
Обычно использование памяти и скорость, как правило, связаны, по крайней мере, с общим объемом. Вы часто можете обнаружить медленное программное обеспечение по тому, как оно загружает память. Не всегда верно, что увеличение объема памяти приводит к замедлению, поскольку важна «горячая» память (к какой памяти обращаются все время - если программа использует загрузочную память, но только 1 мегабайт используется все время, то это не так уж важно по скорости).
Таким образом, вы можете обнаружить потенциальных свиней на основе использования памяти в большинстве случаев. Если приложение при запуске занимает от десятков до сотен мегабайт памяти, оно, вероятно, не будет очень эффективным. Десятки мегабайт могут показаться маленькими, когда у нас есть гигабайты DRAM в наши дни, но самые большие и самые медленные кэши ЦП все еще находятся в мизерном диапазоне мегабайт, а самые быстрые - в диапазоне килобайт. В результате программа, которая использует 20 мегабайт только для запуска и ничего не делает, на самом деле все еще использует довольно «много» памяти с точки зрения аппаратного ЦП, особенно если все 20 мегабайт этой памяти будут доступны повторно и часто, когда программа работает.
Решение
Для меня решение состоит в том, чтобы искать более скоординированные, меньшие команды для создания продуктов, которые могут отчасти отслеживать свои «расходы» и избегать «покупки» одних и тех же товаров снова и снова и снова.
Стоимость
Я окунусь в более противоречивую сторону «затрат», чуть-чуть с феноменом «расходов», который я наблюдал. Если язык в конечном итоге приходит с неизбежным ценником для объекта (например, тот, который обеспечивает отражение во время выполнения и не может вызвать непрерывное выделение для серии объектов), этот ценник является дорогостоящим только в контексте очень гранулированного элемента, такого как одного
Pixel
илиBoolean
.Тем не менее, я вижу много исходного кода для программ, которые обрабатывают большую нагрузку (например, имеют дело с сотнями тысяч до миллионов
Pixel
илиBoolean
экземпляров), оплачивая эти затраты на таком детальном уровне.Объектно-ориентированное программирование может усугубить это. И все же это не стоимость «объектов» как таковых или даже ООП по вине, а просто то, что такие расходы оплачиваются на таком гранулярном уровне крошечного элемента, который будет создан миллионами.
Так что я наблюдаю другие явления «затрат» и «расходов». Стоимость - копейки, но копейки складываются, если мы покупаем миллион банок содовой по отдельности вместо того, чтобы договариваться с производителем о крупной покупке.
Решением здесь для меня является «массовая» покупка. С объектами все в порядке даже в тех языках, в которых каждый имеет цену в несколько копеек, при условии, что эта стоимость не оплачивается отдельно в миллион раз за аналогичный эквивалент банки с газировкой.
Преждевременная оптимизация
Мне никогда не нравилась формулировка Кнута, используемая здесь, потому что «преждевременная оптимизация» редко заставляет реальные производственные программы работать быстрее. Некоторые интерпретируют это как «ранняя оптимизация», когда Кнут имел в виду больше как «оптимизация без надлежащих знаний / опыта, чтобы узнать ее истинное влияние на программное обеспечение». Во всяком случае, практический эффект от истинной преждевременной оптимизации часто собирается сделать программное обеспечение медленнее , так как ухудшение ремонтопригодности средств есть немного времени , чтобы оптимизировать критические пути , которые действительно имеет значения .
Это последнее явление, которое я наблюдал, когда разработчики, стремящиеся сэкономить копейки на покупке одной банки содовой, которую никогда больше не купят, или, что еще хуже, дом, тратили все свое время, зажимая копейки (или, что еще хуже, мнимые копейки из неспособность понять их компилятор или архитектуру аппаратного обеспечения), когда миллиарды долларов были потрачены впустую в другом месте.
Время очень ограничено, поэтому попытка оптимизировать абсолюты без надлежащей контекстной информации часто лишает нас возможности оптимизировать места, которые действительно важны, и, таким образом, с точки зрения практического эффекта, я бы сказал, что «преждевременная оптимизация делает программное обеспечение намного медленнее. "
Проблема в том, что существуют типы разработчиков, которые возьмут то, что я написал выше об объектах, и попытаются установить стандарт кодирования, который запрещает объектно-ориентированное программирование или что-то в этом роде. Эффективная оптимизация - это эффективная расстановка приоритетов, и она абсолютно бесполезна, если мы тонем в море проблем с техническим обслуживанием.
источник
--force
от менеджеров, которые кричали: «Вы будете уволены, если не реализуете это к завтрашнему дню», которые уничтожают годы хорошей практики разработки программного обеспечения, TDD, модульного тестирования и любого человеческого и нормального принципа программирования. Плюс еще два раза, когда вы устали ... тот парень, который покинул компанию из-за того, что был уволен без причины и испортил базу кода ... эти прекращенные библиотеки, которые вы никогда не обновляли ... и вот оно у вас: восхитительная база кода спагетти и раздутый софт. Приятного аппетита