Delphi コード最適化チュートリアル:
文字列の最適化
Delphi には 3 つの文字列タイプがあります。 short string (string[n], n=1..255) 記憶領域は静的に割り当てられ、サイズはコンパイル時に決定されます。これは bp for から継承されます。 dos のタイプである文字配列 (pchar) は、主に bp7 で登場し、現在では文字配列を使用して静的に割り当てることも、getmem を使用して手動で割り当てることもできます。長い文字列 (ansistring) は Delphi に特有のもので、その記憶域は実行時に動的に割り当てられます。これは最も柔軟性があり、悪用されやすいものです。
Delphi のデフォルトの文字列型 AnsiString は、初期化を繰り返さなくても自動的に空に初期化されます。次のコード:
Delphi には 3 つの文字列タイプがあります。 short string (string[n], n=1..255) 記憶領域は静的に割り当てられ、サイズはコンパイル時に決定されます。これは bp for から継承されます。 dos のタイプである文字配列 (pchar) は、主に bp7 で登場し、現在では文字配列を使用して静的に割り当てることも、getmem を使用して手動で割り当てることもできます。長い文字列 (ansistring) は Delphi に特有のもので、その記憶域は実行時に動的に割り当てられます。これは最も柔軟性があり、悪用されやすいものです。
変数:文字列;
始める
s:=;
…
終わり;
s:=;は不要です。ただし、これは関数の戻り値の結果には影響しないことに注意してください。一般に、var 引数を渡すほうが、文字列値を返すよりも高速です。
SetLength を使用して長い文字列 (AnsiString) を事前に割り当ててメモリを動的に割り当てることは AnsiString の大きな利点ですが、典型的な例は次のとおりです。
s2:= ;
for i:=2 to length(s1) do s2:=s2+s1[i];
削除で置き換えられることは言うまでもありませんが、主な問題は、上記の例のループ内で s2 のメモリ領域が繰り返し割り当てられ、非常に時間がかかることです。シンプルで効果的な方法は次のとおりです。
setlength(s2,length(s1)-1);
for i:=2 to length(s1) do s2[i-1]:=s1[i];
このようにして、s2 メモリは 1 回だけ再割り当てされます。
文字列と動的配列のスレッド セーフ Delphi 5 より前では、これらの動的配列と長い文字列に対する操作の非スレッド セーフ呼び出しでは、重要な問題を処理するために参照カウントが使用されていましたが、Delphi 5 以降は、一部の操作に直接変更されました。この問題を回避するには、重要な命令の前にロック命令を付けます。残念ながら、Pentium II プロセッサのロック命令は非常に時間がかかり、この操作を完了するにはさらに約 28 命令サイクルかかるため、この変更は非常に高価であり、そのため全体の効率は少なくとも半分に低下します。この問題を解決する方法は 1 つだけあり、delphi rtl のコア コードを変更することです。元のファイルをバックアップした後、source/rtl/sys/system.pas 内のすべてのロックを {lock} に置き換えます。もちろん、単語全体を置き換える必要があります。これはまだ完全には最適化されていません。次のステップは、delphi4 ランタイム ライブラリにも含まれている xchg 命令を削除することです。この命令には暗黙的なロック プレフィックスがあるため、system.pas の _lstrasg および _strlasg プロセスの xchg edx を削除する必要があります。 [eax] を次のコードに置き換えます。
mov ecx、[eax]
mov[eax]、edx
ムーブedx、ecx
OK、これで完了です。コンパイルして system.dcu を上書きするだけです。これにより、実行効率はdelphi5の6倍、delphi4の2倍になります。