На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила ЧаВо (FAQ) разделов Паскаля
В этом разделе разрешено создавать только темы, в которых описано РЕШЕНИЕ какой-либо общей проблемы, или описание какого-либо аспекта языка Паскаль.
Обсуждение уже созданных тем разрешено, но только конструктивное, например указание на ошибку или уточнение имеющегося текста.

Также читать Требования к оформлению статей
Модераторы: volvo877, Romtek
  
> Советы программисту + Code Tuning
    Советы программисту

    • Не используйте глобальных переменных. Для каждой процедуры создавайте новые. Это реально сократит файл.
    • Очень не слабый эффект уменьшения размера получается при рациональном создании процедур.
      Разбейте программу на модули, так будет легче работать потом.
    • Если вы подключаете целый юнит, используя из него всего 1 процедуру, лучше выдерните эту процедуру из исходников юнита, и вставьте ее в код.
    • Операции с элементами массива всегда выполняются медленнее, чем с обычными переменными.
      Поэтому операция a*b будет выполнена гораздо быстрее, чем a[x]*z[y], при одинаковых значениях
    • Не создавайте много переменных - старайтесь выжать из каждой переменной все, что можно.
      Придавайте переменным осмысленные названия, например, Volume, count.
    • Не вставляйте в свои программы оператор goto. Его использование ухудшает читаемость кода.
    • Также следите за размером переменных в байтах. Не надо использовать большие типы такие как Longint, Extended. В большинстве случаев можно обойтись типом byte и single, а в строках string указывайте кол-во символов string[x]; .
    • Не пользуйтесь глобальными и статическими переменными – это тормозит программу. Пользуйтесь автоматическими, локальными переменными или на уровне модуля. Например локальные переменные процедуры автоматически выбрасываются из памяти по завершению её.
    • Используйте оператор with
    • Кроме того комментировать нужно каждую функцию или процедуру что она делает и каждую структуру.

    Оптимизация кода программ / "Code Tuning"
    • При умножении и делении на 2,4,8,... пользуйтесь shl и shr.
      ExpandedWrap disabled
        inc(x);  {x:=x+1;}
         
        inc(x,N);  {x:=x+N;}
         
        x:=x shr 1;  {x:=x div 2;}
         
        x:=x shl 1;  {x:=x * 2;}
      Примечание: Только для целых чисел!
    • При сравнении вместо
      ExpandedWrap disabled
        (x >= 'A') and (x <= 'Z')
      используйте
      ExpandedWrap disabled
        x in ['A'..'Z']
      (Также можно делать и с числами (точнее байтами), но только от 0 до 255)

      ExpandedWrap disabled
        IF ch IN ['0'..'9','A'..'Z','a'..'z','_'] THEN ...

      лучше заменить на
      ExpandedWrap disabled
        CASE ch OF
              '0'..'9','A'..'Z','a'..'z','_':...;
            END;

    • При работе с множествами операторы
      ExpandedWrap disabled
        Include(S, X) и Exclude(S, X)
      работают быстрее, чем
      ExpandedWrap disabled
        S := S + [X] и S := S - [X]
      соответственно (где S - множество какого-то типа, а X - элемент множества)
    • Превычисления:
      ExpandedWrap disabled
        c := (a + b) * d;
        e := g - (a + b);

      В этих выражениях 2 раза вычисляется a+b, поэтому стоит завести временную переменную,
      ExpandedWrap disabled
        temp := a + b;
        c := temp * d;
        e := g - temp;

    • Пользуйтесь простыми арифметическими операциями начиная по уровню быстроты:
      1) присваивание
      2) сложение,вычитание
      3) умножение
      4) деление
      5) возведение в степень и др.
    • Деление заменяй на умножение:
      ExpandedWrap disabled
        x:=(a+b)/2;
      а надо
      ExpandedWrap disabled
        x:=(a+b)*0.5;

    • Если X и Y целые, то такой код:
      ExpandedWrap disabled
        round­(x/y)
      свободно заменяется на более быстрый:
      ExpandedWrap disabled
        x div y

    • Пишите действительные константы с точкой (10.0 вместо 10). Это предотвращает лишние преобразования.
    • Заменяйте тип real на тип single или double.
    • Используйте move вместо строковых присвоений:
      ExpandedWrap disabled
        move(st1,st2,max_len+1);

    • Используйте ABSOLUTE для переменных с постоянным адресом.
    • I/O может быть улучшен, если используются большие буферы (кратные 512 байтам для оптимальных результатов)

    Но помните,
    "Premature optimization is the root of all evil" © Donald Knuth
      есть пара вопросов
      почему глобальные переменные тормозят программу? Обращение к глобальной переменной идет как mov al,ds:[000a8] т.е. по константе, а к локальной как mov ax,ss:[0fff0][bp], т.е. еще приплетается регистр. Вот переменные в динамической памяти действительно достаются сложнее, чем глобальные или локальные, точный код не приведу, но схема примерно вот такая: les di,dword ptr ds:[000a8]; mov al,es:[di] т.е. два обращения к памяти, причем скорее всего второе место в памяти в кэш процессора не попадет.
      далее, сравнение x in ['A'..'Z'] выполняется как byte[the_set+(x shr 3)] and (1 shl (x and 7))>0 где the_set занимает 32 байта в сегменте констант (скорее всего в коде :() и дважды выполняется операция "достать Х из памяти" (в явном виде 2, на самом деле Паскаль регистры почти не использует, так что может быть и 1), в этом случае проще достать один раз Х и сравнивать его с константами (hard-coded) mov al, byte ptr x; cmp al,'A'; jge dalshe; cmp al,'Z'; jle dalshe; jmp nevyshlo :) а вот с более разорванными множествами целесообразнее применять if X in [...]
      Типа byte не всегда хватает, особенно если потом идет модификация кода с целью увеличить объем обрабатываемых данных, кроме того есть некоторая оптимизация при использовании двухбайтных типов и включенным word align data (возможно, что она устарела). Longint куда попало пихать не следует, это правильно.
      Цитата
      Romtek, 21.09.04, 23:27
      Используйте move вместо строковых присвоений

      странно, я все время думал, что при строковых присвоениях используется именно move()
        Взял большинство советов со странички по адресу http://www.stevemcconnell.com/cctune.htm
        А вообще моих советов тут немного...
          Для очистки множеств лучше использовать это:
          ExpandedWrap disabled
            FillChar(x,SizeOf(x),0);

          где х - заданное множество.

          По сравнению с x:=[] прирост скорости ~1.5 раз....
          Сообщение отредактировано: Romtek -
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0305 ]   [ 16 queries used ]   [ Generated: 20.02.24, 22:17 GMT ]