Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Быстрее, еще быстрее

Оформил: DeeCo

Автор: Еремеев Алексей

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

Насчет таблиц перекодировок и трансляции (преобразованию данных) вообще.

Любимый прием программистов (и я через это проходил) создавать цикл трансляции строк вида (для простоты возьмем случай, когда выполняется преобразование байт-в-байт, вроде перекодировок ANSI-DOS):
function TranslateString(Source: string): string;
var
  i: integer;
begin
  Result := '';
  for i := 1 to Length(Source) do
    Result := Result + TranslateChar(Source[i]);
end;
Это ужасно медленно! Загвоздка тут в конструкции Result := Result + ...
Каждый раз при добавлении одного байта к строке происходит переаллокация памяти и копирование уже существующего начала в новую область памяти, потом удаление старой области.
Я бы сделал процедуру с var параметром и делал бы в цикле так:
procedure TranslateString(var Source: string);
var
  i: integer;
begin
  for i := 1 to Length(Source) do
    Source[i] := TranslateChar(Source[i]);
end;

Или, если очень нужна функция, то так:

function TranslateString(const Source: string): string;
var
  i: integer;
begin
  SetLength(Result, Length(Source));
  for i := 1 to Length(Source) do
    Result[i] := TranslateChar(Source[i]);
end;
А уж пример трансляции с обратным поиском (см. Вариант1 Таблиц перекодировки на http://www.delphikingdom.com/treasury/decod.htm) - это вообще ночной кошмар микропроцессора!
Если нет прямой таблицы преобразования, ее нужно сначала создать из обратной (одного раза за сеанс достаточно :-), а потом ее использовать.

Что лучше? (Вопросы от Сашы)

>> И вот для меня не очевидно чем первое лучше второго.
if A > B then
  C := A
else
  C := B;
и
C := A;
if A < B then
  C := B;

Очевидно. Во втором случае присваивание C:=A будет выполнятся в любом случае, даже если A<B. Налицо лишняя команда. Хотя в разных случаях может быть по разному.
Что лучше, лишний MOV или лишний JMP ? А если строки присваиваются?

>> А конструкции if then else if then .... И сase of

Тут все зависит от конкретной ситуации. Если речь идет о перечислимых типах, то скорее всего лучше подойдет case. С точки зрения исходного кода эти две конструкции равнозначны. А вот если нужно сравнивать строки, то case тут не поможет. (поправьте, если я не прав)

>> A for i:=0 to 10 do И i:=0; while I<=10 do i:=i+1;

И тут все зависит от ситуации. В ощем виде можно сказать так, что цикл while необходим в следующих случаях:
  1. когда шаг цикла может меняться внутри цикла
  2. когда кол-во итераций может менятся внутри цикла
  3. когда используется значение переменной цикла после выхода из цикла

>> И классический пример рекурсии

function Factorial(N: Longword): Longword;
begin
  Result := 1;
  if N < 1 then
    exit;
  Result := N * Fuctorial(N - 1);
end;
И

function Factorial(N: Longword): Longword;
var
  I: Longword;
begin
  Result := 1;
  for I := 1 to N do
    Result := Result * I;
end;

Рекурсия - вообще дело тонкое :-) Снова надо говорить о частностях. Первое, о чем надо подумать, это максимально возможная глубина спуска. Если есть вероятность переполнения стека - сразу отбрасывайте прямой рекурсивный способ.
Если уж никак не обойтись без глубокой рекурсии, можно реализовать что-то типа суррогатного стека ручным способом. Это муторно однако. Ну и если есть простой итеративный способ - на мой взгляд лучше воспользоватся им. (Хотя согласен - изящная рекурсия - оч-ч-чень красиво!)

Итог

В общем случае, если не касаться специальных математических методов оптимизации в предметной области то исходить нужно из исходной задачи и здравого смысла. Хотя здравый смысл нужен всегда :-)
Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay