pyscripter 689 Posted February 20, 2022 (edited) I was trying to improve the performance of SynEdit in handling files with super long lines (e.g. 50K characters). In doing so I came across an unexpected optimization that had a spectacular impact on performance. See this innocent looking function probably written two decades ago (fCasedLine is a PChar): function TSynCustomHighlighter.GetToken: string; var Len: Integer; begin Len := Run - fTokenPos; SetLength(Result, Len); if Len > 0 then StrLCopy(@Result[1], fCasedLine + fTokenPos, Len); end; By measuring I found that this function (called zillions of times) was a bottleneck and replaced it with: function TSynCustomHighlighter.GetToken: string; var Len: Integer; begin Len := Run - fTokenPos; SetString(Result, fCasedLine + fTokenPos, Len); end; The impact was massive. Both SetString and StrLCopy in x64 are implemented in pascal (not assembly) using Move. So initially I was puzzled. However here is the reason. Look at StrLCopy: function StrLCopy(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; var Len: Cardinal; begin Result := Dest; Len := StrLen(Source); if Len > MaxLen then Len := MaxLen; Move(Source^, Dest^, Len * SizeOf(WideChar)); Dest[Len] := #0; end; Can you see the problem? It is the call to StrLen(Source)! In my case the Source was very very long strings, the length of which was unnecessarily calculated the hard way. The lesson here is that you need to identify the bottlenecks by measuring. You may be in for surprises, sometimes pleasant ones, Edited February 20, 2022 by pyscripter 9 Share this post Link to post
MarkShark 27 Posted February 20, 2022 Wow! I've actually been bitten by strlen in the past. Well done sir!! Share this post Link to post
Edwin Yip 154 Posted February 20, 2022 Well done sir! BTW, what tool(s) do you use to measure the performance? Thanks. Share this post Link to post
pyscripter 689 Posted February 20, 2022 27 minutes ago, Edwin Yip said: BTW, what tool(s) do you use to measure the performance? TStopwatch and occasionally VTune. 1 Share this post Link to post
Guest Posted February 20, 2022 SetString can raise a "EOutOfMemory" or not initialize target string... 🧐 Share this post Link to post