ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
 
 
Опции темы Поиск в этой теме Опции просмотра

Кодерские tips and tricks
  #1  
Старый 16.11.2006, 15:48
Аватар для TaNkist
TaNkist
Участник форума
Регистрация: 06.04.2006
Сообщений: 257
Провел на форуме:
367179

Репутация: 76
По умолчанию Кодерские tips and tricks

Кодерские tips’n’tricks

В данной теме делимся программерскими трюками. Это могут быть советы по оптимизации, нестандартные приемы, интересные (но не слишком большие) куски кода. Не стоит превращать тему в свалку исходников, выбирайте наиболее интересные и полезные участки кода. Желательно откомметировать трюк, чтобы всем было понятно.
Delphi
Оптимизация

[Передача аргументов] Никогда не передавай функции в качестве параметра структуру, лучше передавать указатель на нее
Код:
//Ни в коем случае не делай так.
Procedure code (Data:TStructure);
//Правильный вариант
Procedure code (PData:PStructure); //гда PStructure = ^TStrucrure
Старайся передавать своим функциям не более трех параметров, т.к. они передаются через регистры (по соглашению fastcall, принятом по умолчанию в Delphi), а все остальные через стек.
[Функции - инварианты] Довольно распространенная ошибка программистов – присутствие функций - инвариантов в цикле.
Код:
//Неоптимизированный вариант
While i<= lstrlen(str) do
Begin
X:=x+ord(str[i]);
Inc(i);
End;
Очевидно, что длина str не меняется, но компилятор считает, что все, что передается по ссылке сожжет быть изменено, и lstrlen вычисляется много раз. Оптимизированный вариант выглядит так.
Код:
//Так лучше
N:=lstrlen(str);
While i<= n do
Begin
X:=x+ord(str[i]);
Inc(i);
End;
[Экономия памяти] Когда класс располагается в памяти, то между полями появляются пустые ячейки памяти. Это происходит потому, что Delphi, оптимизируя код, каждое поле располагает от предыдущего со сдвигом в 4 байта.
Код:
// Неоптимизированный вариант
TMyClass = class
  private
    field1: boolean;//1 байт
    field2: longint; //4 байт
    field3: char; //1 байт
    field4: string; //4 байт
    field5: byte; //1 байт
    field6: integer; //4 байт
    field7: byte; //1 байт
  public
    procedure code;
end;
Реально этот экземпляр класса будет занимать 28 байт. Если мы изменим порядок полей, то сможем добиться уменьшения размера до 16 байт. В нашем примере после field1 размером 1 байт идет field2 размером 4 байта, значит, мы теряем 3 байта на выравнивание. Если же размер field2 не превышал 3 байт, то Delphi не стал бы выравнивать, а поместил бы это поле сразу после первого.
Код:
// Оптимизированный вариант
TMyClass = class
  private
    field1: boolean; //1 байт
    field3: char; //1 байт
    field5: byte; //1 байт
    field7: byte; //1 байт
   field2: longint; //4 байт
    field4: string; //4 байт
    field6: integer; //4 байт
  public
    procedure code;
end;
[Компиляция без RTL (Run Time Library)] Как известно минимальный размер скомпилированной в Delphi программы с настройками по умолчанию равен 13,5 Кб. Виной тому принудительно подключаемая Delphi RTL, в которой реализованы некоторые возможности языка Delphi.
Для уменьшения размера скомпилированных прог исправим модели System.pas и SysInit.pas, удалив все «лишнее». Затем перекомпилируем их и полученные dcu-файлы поместим в папку с прогой.
Минимальный System.pas
Код:
unit System;

interface

procedure _HandleFinally;

type
 TGUID = record
  D1: LongWord;
  D2: Word;
  D3: Word;
  D4: array [0..7] of Byte;
 end;

 PInitContext = ^TInitContext;
 TInitContext = record
    OuterContext:   PInitContext;   
    ExcFrame:       Pointer;          
    InitTable:      pointer;     
    InitCount:      Integer;          
    Module:         pointer;       
    DLLSaveEBP:     Pointer; 
    DLLSaveEBX:     Pointer; 
    DLLSaveESI:     Pointer;   
    DLLSaveEDI:     Pointer;   
    ExitProcessTLS: procedure;     
    DLLInitState:   Byte;             
 end;

implementation

procedure _HandleFinally;
asm
end;

end.
Минимальный SysInit.pas
Код:
unit SysInit;

interface
procedure _InitExe;
procedure _halt0;
procedure _InitLib(Context: PInitContext);

var
  ModuleIsLib: Boolean;        
  TlsIndex: Integer = -1;       
  TlsLast: Byte; 

const
  PtrToNil: Pointer = nil;   

implementation

procedure _InitLib(Context: PInitContext);
asm
end;

procedure _InitExe;
asm
end;

procedure _halt0;
asm
end;
end.
Компиляция
Код:
Dcc32.exe – Q System.pas SysInit.pas –M –Y –Z -$D- -O
Некоторые трюки

[Обмен] Обмен значений между двумя переменными без привлечения третьей.
Код:
x:=x xor y;
y:=y xor x;
x:=x xor y;
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
10 tips & tricks for C/C++ windows programming with Visual C++ 6.0 Dracula4ever Forum for discussion of ANTICHAT 0 30.05.2006 17:11



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ