Любая процедура или функция - это потеря в скорости. Чтобы понять это, необходимо знать, как программа переходит на выполнение процедуры и выходит из нее.

Функции и процедуры работают практически одинаково. Разница состоит только в возвращаемом значении, поэтому в дальнейшем все, что я буду говорить о процедурах, в равной степени относится и к функциям.

Вызов процедуры в программе в виде псевдокода можно представить следующим образом:

Код программы Код программы Вызов процедуры Код программы

Начало процедуры Код процедуры Конец процедуры

Код других процедур или программы

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

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

Все параметры процедур и функций передаются через специальную память, которая называется стеком. Перед началом процедуры параметры помещаются в стек, а перед выходом убираются из него. Таким образом, если передавать только один параметр, то используются как минимум две операции процессора (поместить переменную и взять из стека).

Несмотря на то, что работа со стеком происходит достаточно быстро и есть специальные инструкции упрощающие работу (push и pop), при большом количестве параметров или их большем размере потери могут оказаться существенными. А если добавить сохранение/восстановление регистров процессора при вызове процедуры, сохранение и получение адреса возврата, то это уже существенно.

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

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

В Delphi, чтобы переменная, которую мы передали процедуре, не могла изменяться, ничего делать не надо Если необходима возможность изменения ее содержимого из процедуры, то перед объявлением соответствующего параметра нужно поставить слово var.

При передаче в Delphi объектов или адресов процедуре всегда передается именно адрес на объект или данные, поэтому через этот адрес процедура может изменить данные, и они не восстановятся после выхода.

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

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

Когда код процедуры небольшой и вызывается 2-3 раза, можно отказаться от применения процедуры, скопировав код в нужные места. В этом случае одинаковые участки кода будут встречаться несколько раз, что увеличит размер программы, но при этом производительность может повыситься.

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

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

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

2.6. Оптимизация циклов || Оглавление || 2.8. Сложные расчеты


Delphi в шутку и всерьез: что умеют хакеры



Новости за месяц

  • Ноябрь
    2021
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс