utilizzare in un sacco nel mio progetto e ho un sacco di questi avvertimenti:CharInSet è molto più lento di IN, dovrei correggere il suggerimento di avviso W1050?
[DCC Attenzione] Unit1.pas (40): W1050 WideChar ridotto a char byte espressioni set. Prendi in considerazione l'utilizzo della funzione CharInSet nell'unità SysUtils.
Ho fatto un test rapido e l'utilizzo di CharInSet al posto di IN è da 65% -100% più lento:
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
vs
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
Ecco il codice per 2 test, si lavora con loop attraverso stringhe più corte, un loop una volta attraverso una stringa grande:
Aggiunta di 2 pulsanti sul modulo Ho provato questo per una stringa breve:
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;
E questo per 1 lunga serie:
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;
Perché si consiglia l'opzione più lenta, o come posso risolvere questo avvertimento senza penalità in termini di prestazioni?
Dai uno sguardo a http://stackoverflow.com/questions/332948/why-is-charinset-faster-than-case-statement – RBA
Ho visto quella domanda, ma l'ho respinta a causa del titolo - non posso rad tutto . Ma include alcune informazioni preziose. –
Qualcuno può spiegare se questo avviso è rilevante o meno in questo caso? Il set contiene solo caratteri ascii e se 's1 [i]' è un carattere wide, il compilatore delphi win32 genera il codice corretto per quel confronto. Ho provato 's1: = '£'; se (s1 [1] in ['A']) allora ... ', perché' Byte ('Ł') = 65 = Byte ('A') '. Ma per questo confronto il compilatore genera il codice corretto. – ventiseis