Искусство программирования на Си (984073), страница 13
Текст из файла (страница 13)
Так что, если ваши строки достаточно длинные, это даст существенное ускорение всего процесса. На протяжении длительного времени считалось„что операции над числами с плаваюшей точкой более медлительны по сравнению с операциями над целыми числами. Однако в течение последних нескольких лет операции с плавающей точкой выполняются так же быстро, как и нх целые аналоги.
Используя соответствующим образом арифметику плаваюшей точки в своей программе, вы мозкете лостигнуть некоторых оптимизационных целей: 1. Часто преобразования целых чисел в числа с плаваюшей точкой нли наоборот снова и снова не ° /)ерымоыренныд язых С Часть ! Озяяимизаиия Глава 3 сиональной литературе означает снижение эффективности работы системы с виртуальной памятью вследствие чрезмерного количества запросов на подкачку страниц.— Лрияь науч. ред.).
Вы можете воздействовать на локальность ссылок путем изменения порядка, в котором осуществляете доступ и размещаете объекты памяти, такие как массивы, или путем разбиения структур данных на часто используемые и редко используемые сегменты и разместить все часто используемые наборы вместе. Не счелует полагать, что функция пшйос всегда размещает рядом вплотную друг к другу области памяти при казкдом последовательном вызове. Вы должны разместить одну гигантскую область самостоятельно, чтобы быль в этом уверенным.
Но это может привести к другим проблемам. Алгоритмы поиска и сортировки в широких пределах различаются между собой в разнообразии доступа к памяти. Сортировка слиянием часто рассматривается как имеющая лучшую локальность ссылок. В отноше- Гвг () = 0; З < 100/ )++) /я заметьте, что ) — ваутревввй ввдехс '/ [ аггау [з.) [)) " 0.0," ) Некоторые дополнительные стратегии оптимиаации Если вы исчерпали все возмозкные алгоритмы и оптимизацию реализации и, несмотря на это, отчаялись добиться хоть небольшого повышения скорости работы своей программы, можете подумать об оптимизации вне комфортабельного контекста языка программирования С. Один подход, на который некоторые уповают, состоит в записи наиболее критичных ко времени разделов вашего кода на языке ассемблера.
Я не являюсь безусловным сторонником такого совета, поскольку если вы недостаточно хороший программист, чтобы написать рует наиболее быстро выполняемый код. Типичные различия между высококачественными компиляторами измеряются 2-5% скорости сгенерированного кода (это лля сведения о том, почему автор тщательно выбирает компилятор лля оптимизации). Другим решением, связанным с программным обеспечением, является использование соответствующего коммерческого продукта, такого как пакет базы данных или библиотеки численного анализа. Это позволит вам получить преимущество от хорошо оптимизированного программного обеспечения, которое иначе не попало бы в ваше распоряжение и которое может содержать некоторые лицензионные средства повышения скорости, которые ни мне, ни вам никогда бы не удалось заполучить другим п)чем.
Но не все можно получить за деньги, и не все программы могут стать воплощением легендарной напористости языка ассемблера. Какую же еше простую и доступную стратегию мы можем применить? Это— терпение. В соответствии с законом Мура, вычислитель- нять одновременно только одну программу. Для таких примитивных систем программисты могли позволить себе только повышать уровень использования ресурсов компьютера (диска, памяти, контроллеров ввода/вывода). По существу, неаккуратное использование ресурсов вредило только их собственным программам, но коль скоро делалась какая-то полезная работа по крайней мере одной подсистемой, то попытки сделать работу других подсистем более эффективной не могли увенчаться успехом, поскольку устройства все равно должны были просто находиться в ожидании, если они заканчивали выполнение своих задач раньше. (Чтобы это было похоже на правду, напомню вам, что все только что упомянутые признаки применимы к МБ-ООЬ.) Многозадачные, многопользовательские и серверные операционные системы изменили эту ситуацию.
Когла ваша программа заканчивает использование ресурсов, мозкет начать выполняться другая задача, которая раньше находилась в ожидании. Это хорошо. Но теперь не- Перегяомреиаай хзик С Часть 1 Оятимизач х ЩЕЯИ -идф Глава 3 ° Способность пакетирования (Вцгз((пезз) — возмож ность быстрой последовательности запросов на ре суре и пауз неактивности мсжд) них~и. этим ресурсом. Обычно измеряется в милли- или Другим решением может стать использование мно- Сначала рассмотрим естественные объемы (или раз- Такая программа нс будет выполняться так, как она микросе куплях. гопоточного пакета, с тем чтобы разрешить одной час- меры), с которыми работают устройства.
Для диска этот выполнялась бы на суперкомпьютере, но на хорошей ти вашей клиентской программы ждать ответа от сср- сстсствснный размер составляет обычно умеренное чис- операционной системе она даст возможность намного вера (с использованием сблокированного протокола), но ло — 512 или 1024 байта. Подсчитаем, как много запи- лучше распределить процсссную нагрузку. дать другим потокам на вашем клиенте продолжать про- сей (из вашего файла) требуется для заполнения сдннизволитсльную работу.
Этот метод используется многи- ствснного блока диска (скажем, всего блоков 8), н это ПОЛЬЗОВВТЕЛЬСКИИ ИНТЕРфЕИС ДЛЯ ми %сЬ-браузсрами, позволяющими загружать множс- даст нам идею, насколько уменьшить единицу работы, МЕДЛИТЕЛЬНЫХ аЛГОРИТМОВ ство страниц и множество изображений одновременно, которая обеспечит полное использование функции чтсТеперь наша функция трехфазного копирования запинссмотря на то что лежашии в их основе протокол НТТР ния диска.
Мы пойдем немного далее и предположим, сей с лиска выполняется заметно быстрее, чем прежде, является сблокированным. Этот подход имеет тот не- что в операционной системе или на жестком лиске имено она все еше может занимать целую минуту. Если бы достаток, что большая часть вашего кода должна быть ется один нли два уровня буферизации и что они моКлиент-сервер и параллелизм переписана так, чтобы следовать модели управления тут фактически обработать несколько поставленных в ет графический пользовательский интерфейс, то наша Вы могли бы подумать, что если у вас есть лва комль- потоками выполнения вашей программы, а в мультипо- очередь запросов. Но нам здесь нс нужно загружать ус- О программа была бы безответна к вводу пользователя, н, ютера, один из которых выполняет клиентскую про- токовой программе нскоторыесвойстваС ведутсебя по- тройство на все 100,е цикла режима работы.
Нам толь- поскольку он бы не знал, когда она снова станет отве- грамму, а второй — серверную, то, когда две програм- разному нлн непредсказуемо. ко необходимо задать ему достаточно работы для того, чать на запросы, у него бы появилось большое желание мы связаны между собой, они могли бы выполняться в Если быть честным, то в С нет понятия клиент-сер- чтобы мы могли начать работать с какой-либо сше часкаждый раз прерывать программу в самый неподходя- нскотором смысле параллельно и закончиться вдвое око- вер, нет параллелизма и нет межпроцессной коммуни- тью программы, пока диск занят чтением.
Но следует шии момент рсе, чем в том случае, если бы они работали последо- канин. Ни одно из этих свойств не может быть постро- опасаться задавать дисководу так много работы, что вся Самое простое, что можно сделать в такой ситуации,— ватсльно. Ответ на этот вопрос зависит от того, какой ено в рамках языка илн стандартной библиотеки. программа будет ждать, пока он ее закончит ... Этв ИЗМСН!1тЬ.,КУРСОВ, ЦаюПЛСОХНмЫЕ,ЧУСЫЬ И, Датъ таКИМ дог Оимимиыиия Лересмиыреиини изми С Глава 3 Часть! тускнс теряет терпение, то ваша программа будет первой знать об этом и вы сможете ответить.
Например, вы можете восстановить любую частично завершенную запись или удалить временные файлы либо даже ответить, что операция будет завершена позже, когда пользователя нет рядом, и что он может не беспокоиться. Без кнопки Отмена пользователь будет прекращать выполнение вашей программы насильно, а это может спутать все данные, с которыми в этот момент работала программа. Если случайно вы последуете всем этим советам о полосах развития процесса и кнопке Отмена, то можете столкнуться с неприятным фактом. На обновление экрана, проверку на нажатие пользователем кнопки Отмена и вызовы операционной системы из вашей программы затрачиваются время и усилия компьютера, даже если нет необходимости выполнять все эти действия.
Эта дополнительная работа может сушественно замедлить выполнение вашей программы. Из собственных экспериментов я обнаружил, что Когда оптимизация не нужна В своих попытках сделать программу как можно более быстрой, необходимо помнить, что оптимизация обычно должна быть последней стадией процесса разработки и вообще должна быть скоординирована с другими целями программного обеспечения. Ниже представлены некоторые заключительные слова мудрости, которые помогут вам сберечь драгоценное время и усилия в процессе вашей оптимизационной деятельности. Корень зла — в преждевременной оптимизации Самым плохим временем для оптимизации является момент, когда вы начинаете писать код.
Конечно, это то время, когда вы лолжны сделать выбор эффективного алгоритма. Но код, который вы пишете, не должен ть из-за каких-либо мыслей об экономии машин- оптимизации. Сейчас наиболее важно. чтобы другие программисты были способны понять ваш код так, чтобы, когда наконец наступит время оптимизации. каждый из них имел ясное представление о том, какие функции выполняет кол, а не сталкивался кажлый раз с проблемами или постоянно просил вас объяснить смысл некоторых необычных строк кода. И конечно, наиболее преждевременной мо:кно считать оптимизацию, которую вы делаете без предварительного использования профиля или другого инструмента измерений. Легче сделать корректную программу быстрой, чем быструю программу корректной Значительно лучше начать с разработки фрагмента кода и попытаться улучшить его, чем разбить код на фраг- менты, а затем пытаться собрать их вместе.