|
Программирование >> Оптимизация возвращаемого значения
Излишнее создание и удаление объектов для программы подобно кровотечению, когда драгоценное время неумолимо истекает при каждой операции с ненужным объектом. Эта проблема настолько актуальна, что я вынужден посвятить четыре отдельных раздела описанию того, откуда берутся такие объекты и как от них избавиться, не нарушив корректной работы программы. Создание слишком большого количества объектов не единственная причина, по которой увеличивается размер программы и замедляется ее выполнение. Среди прочих выбоин необходимо отметить неправильный выбор библиотек и путей реализации возможностей языка. Эти проблемы также затрагиваются в настоящей главе. Из5ая материал данной главы, вы ознакомитесь с некоторыми принципами, которые способны улучшить производительность практически любого приложения. Вы узнаете, как предотвратить попадание ненужных объектов в ваши программы, а также будете иметь более четкое представление о том, как компиляторы ведут себя при создании исполняемых файлов. Говорят, кто предупрежден, тот вооружен. В таком случае расценивайте следующую информацию как подготовку к битве. Правило 16. Не забывайте о правиле 80-20 Правило 80-20 гласит, что 80% программных ресурсов и памяти используется примерно 20 процентами кода программы: 80% времени уходит на выполнение примерно 20% кода, 80% обращений к диску осуществляется примерно из 20% кода, 80% усилий по поддержке тратится примерно на 20% кода. Правило 80-20 неоднократно проверялось на различных компьютерах, операционных системах и приложениях. Это не просто запоминающаяся формула, а оценка производительности системы, широко применяемая и имеющая солидную эмпирическую основу. При рассмотрении правила 80-20 очень важно не слишком вдаваться в цифры. Некоторые считают более точным соотношение 90-10 , которое также подтверждается экспериментально. Независимо от точности цифр суть остается неизменной: суммарная производительность программы почти всегда определяется небольшой частью кода, лежащей в ее основе. Правило 80-20 как упрощает, так и усложняет жизнь программиста, стремящегося увеличить производительность своей программы. С одной стороны, правило 80-20 подразумевает, что большая часть создаваемого вами кода может, честно говоря, иметь довольно среднюю производительность, поскольку в течение 80% времени его эффективность не влияет на суммарную производительность системы, над которой вы работаете. Это, конечно же, не льстит самолюбию любого программиста, но должно немного охладить ваш пыл. С другой стороны, правило подразумевает, что если возникают проблемы с производительностью, то вам предстоит хорошенько поработать, чтобы не только обнаружить участки неэффективного кода, но и найти способ, как их усовершенствовать. Обычно сложнее всего найти узкие места . Существует два абсолютно разных подхода к данной проблеме: тот, который используется большинством программистов, и правильный. Большинство программистов стараются просто угадать, где находятся критические участки кода. На основе опыта, интуиции, карт Таро и спиритических сеансов, слухов или чего-нибудь похуже, разработчик за разработчиком торжественно объявляют, что проблемы эффективного функционирования программ восходят к сетевым задержкам, плохо настроенному распределению памяти, к компиляторам, которые плохо выполняют оптимизацию, или к запрету тупоголовыми менеджерами использовать язык ассемблера для критических внутренних циклов. Подобные оценки обычно высказываются со снисходительной усмешкой, но, как правило, и сами насмешники, и их прогнозы оказываются совершенно несостоятельными. Почти все программисты обладают отвратительной интуицией в том, что касается характеристик производительности их программ, так как эти характеристики сами по себе обычно совершенно не интуитивны . И в результате невообразимые усилия тратятся на повышение эффективности тех частей программы, которые не оказывают ошутимого влияния на ее суммарное поведение. Например, представим, что в программу можно добавить замечательные алгоритмы и структуры данных, снижающие вычислительные затраты, но, если производительность программы ограничивается возможностями ввода-вывода, то все усилия будут потрачены зря. Конечно, нетрудно заменить поставляемые с компилятором библиотеки ввода-вывода на более мощные (см. правило 23), но это не даст значительных изменений, если использующие их программы ограничены техническими параметрами процессора. Что же делать в случае, если ваша программа работает слишком медленно или требует чрезмерно много памяти? Согласно правилу 80-20 , совершенствование выбранных наугад частей программы вряд ли исправит положение. Производительность программы обычно определяется не слишком явными характеристиками, поэтому попытки найти наугад причину падения производительности ничем не отличаются от простого усовершенствования произвольно выбранных частей программы. Что же вам поможет в этом случае? Самое эффективное средство - эмпирически, то есть при помощи отладчика, определить те 20% программы, которые причиняют вам головную боль . Но не всякий отладчик подойдет для этой задачи. Вам необходим такой, чтобы непосредственно измерял интересующие вас ресурсы программы. Например, если программа работает слишком медленно, то необходимо использовать отладчик, который измеряет время, затрачиваемое на выполнение ее отдельных участков. Это позволит вам сконцентрироваться на тех местах, где усовершенствование локальной эффективности вызовет значительное улучшение суммарной работоспособности приложения. Польза от отладчиков, определяющих, сколько раз выполняется каждый оператор, сколько раз вызывается каждая функция, скажем прямо, невелика. С точки зрения производительности эти сведения совершенно не важны. Мало кого из пользователей программ или подключаемых библиотек интересует число выполненных операторов или вызовов функций. Единственное, что имеет для них какое-либо значение, - время. Пользователи ненавидят ждать, а если ваша программа заставляет их это делать, то они ненавидят и вас. Тем не менее, знание частоты выполнения операторов и вызова функций может иногда пролить свет на то, как функционирует программа. Если, например, вы создаете около сотни объектов определенного типа, вам будет небезынтересно узнать, что при этом конструкторы в данном классе вызываются уже не сотни, а тысячи раз. Более того, подсчет числа вызовов операторов и функций иногда помогает понять скрытые аспекты поведения программы. Если вы, например, не имеете прямой возможности оценить использование динамической памяти, то вам пригодится информация о том, как часто вызываются функции выделения и освобождения памяти (например, операторы new, new [], delete и delete [ ] -см. правило 8). Конечно, даже лучшие из отладчиков являются заложниками обрабатываемых данных. Не удивляйтесь, когда при обработке нетипичных входных данных отладчик укажет, что требуется доводка части программы, попадающей в 80%, хотя, как вы знаете, это никак не отражается на общей работе программы. Помните, что отладчик может сообщить вам о поведении приложения во время конкретного прогона (или нескольких прогонов ), поэтому если вы отлаживаете программу, используя нетипичные входные данные, то в итоге получите нетипичные значения измеряемых параметров. Это, в свою очередь, приведет к тому, что вы будете оптимизировать работу программы для нетипичного случая, а общий эффект может быть даже отрицательным. Л5Д1Ший способ избежать таких патологических результатов заключается в том, чтобы отлаживать программу, используя как можно больше различных наборов входных данных. Кроме того, вы должны убедиться, что каждый набор данных типичен для клиентов (или по крайней мере для наиболее важных из них). Типичный набор данных обычно пол5ить легко, потому что многие пользователи с удовольствием предоставят в ваше распоряжение свои данные для отладки. В таком случае вы будете настраивать программное обеспечение, исходя из их потребностей, и от этого выиграют все. Правило 17. Используйте отложенные вычисления с точки зрения эффективности наил5шими вычислениями являются те, которые вообще никогда не выполняются. Но зачем помещать такой код в программу? А уж если по каким-либо причинам без данного кода в программе не обойтись, как избежать его выполнения? Выход в том, чтобы отложить вычисления. Помните, когда вы были еще ребенком, родители заставляли вас убирать свою комнату? Если вы были похожи на меня в детстве, то сказали бы: Хорошо , а затем быстро вернулись к тому, чем занимались до этого. Фактически, уборка 4-679
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |