私は私のプロジェクトでロットの使用して、私はこれらの警告をたくさん持っている:CharInSetはINよりもはるかに低速ですが、W1050警告ヒントを修正する必要がありますか?
[DCC警告] Unit1.pas(40):W1050がWideCharは セット式でバイト文字に減少しました。 SysUtilsユニットでCharInSet関数を使用することを検討してください。
私は簡単なテストをしたし、代わりにINのCharInSetを使用すると、65%から100%に遅いです:
if CharInSet(s1[i], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']) then
対
if s1[i] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] then
ここ2回の試験では、1つの作品のためのコードがあります短い文字列のループでは、大きな文字列に1回ループします。
フォームに2つのボタンを追加しました。私は短い文字列のためにこれをテストしました:
procedure TForm1.Button1Click(Sender: TObject);
var s1: string;
t1, t2: TStopWatch;
a, i, cnt, vMaxLoop: Integer;
begin
s1 := '[DCC Warning] Unit1.pas(40): W1050 WideChar reduced to byte char in set expressions. Consider using CharInSet function in SysUtils unit.';
vMaxLoop := 10000000;
cnt := 0;
t1 := TStopWatch.Create;
t1.Start;
for a := 1 to vMaxLoop do
for i := 1 to Length(s1) do
if s1[i] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] then
inc(cnt);
t1.Stop;
cnt := 0;
t2 := TStopWatch.Create;
t2.Start;
for a := 1 to vMaxLoop do
for i := 1 to Length(s1) do
if CharInSet(s1[i], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']) then
inc(cnt);
t2.Stop;
Button1.Caption := inttostr(t1.ElapsedMilliseconds) + ' - ' + inttostr(t2.ElapsedMilliseconds);
end;
そして、このための1つの長い文字列:
procedure TForm1.Button2Click(Sender: TObject);
var s1: string;
t1, t2: TStopWatch;
a, i, cnt, vMaxLoop: Integer;
begin
s1 := '[DCC Warning] Unit1.pas(40): W1050 WideChar reduced to byte char in set expressions. Consider using CharInSet function in SysUtils unit.';
s1 := DupeString(s1, 1000000);
s1 := s1 + s1 + s1 + s1; // DupeString is limited, use this to create longer string
cnt := 0;
t1 := TStopWatch.Create;
t1.Start;
for i := 1 to Length(s1) do
if s1[i] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] then
inc(cnt);
t1.Stop;
cnt := 0;
t2 := TStopWatch.Create;
t2.Start;
for i := 1 to Length(s1) do
if CharInSet(s1[i], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']) then
inc(cnt);
t2.Stop;
Button2.Caption := inttostr(t1.ElapsedMilliseconds) + ' - ' + inttostr(t2.ElapsedMilliseconds);
end;
は、なぜ彼らが遅くオプションをお勧めしますか、またはどのように私はパフォーマンスのペナルティなしでこの警告を修正することができますか?
http://stackoverflow.com/questions/332948/why-is-charinset-faster-than-case-statement – RBA
私はその質問を見ましたが、タイトルのためにそれを却下しました。 。しかし、それはいくつかの貴重な情報を含んでいます。 –
この場合、この警告が関連するかどうかを誰かが説明できますか?このセットにはascii文字しか含まれておらず、 's1 [i]'がワイド文字の場合、delphi win32コンパイラはその比較のための正しいコードを生成します。私は 's1:= 'Ł'を試した。 'Bytes('Ł ')= 65 = Byte(' A ')'のため、if(['A'])のthen(s1 [1])then ...しかし、この比較のために、コンパイラは正しいコードを生成します。 – ventiseis