I use IN a lot in my project, and I have a lot of these warnings:
[DCC Warning] Unit1.pas (40): W1050 WideChar shortened to char byte in set expression. Consider using the CharInSet function in the SysUtils module.
I did a quick test and using CharInSet instead of IN with 65% -100% slower:
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
Here is the code for 2 tests, one works with a loop through shorter lines, one loop once through a large line:
Adding 2 buttons in the form I checked for a short line:
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;
And this is for 1 long line:
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;
Why do they recommend a slower option, or how can I fix this warning without a performance penalty?