class function TIWBaseForm.TextToHTMLStringLiteral(aText: string): string; var f : integer; begin Result := ''; for f := 1 to Length(aText) do begin if (AnsiChar(aText[f]) in ['A'..'Z', 'a'..'z', '0'..'9', ',', '.', '-', '_']) then begin Result := Result + aText[f]; end else begin Result := Format('%s%d;', [Result, Ord(aText[f])]); end; end; end;Here we can see the same pattern we found in the previous modified methods. We will use the same kind of construction - and the same runtime patching technique - to replace this method with a faster one, during execution. The new TextToHTMLStringLiteral is shown below:
class function TIWBaseForm.TextToHTMLStringLiteral(aText: string): string; const NoConversion = ['A'..'Z', 'a'..'z', '0'..'9', ',', '.', '-', '_']; var Sp, Rp: PChar; begin SetLength(Result, Length(AText) * 8); Sp := PAnsiChar(AText); Rp := PAnsiChar(Result); while Sp^ <> #0 do begin if (Sp^ in NoConversion) then begin Rp^ := Sp^; end else begin Inc(Rp, FormatBuf(Rp^, 7, '%.4d;', 7, [Ord(Sp^)]) - 1); end; Inc(Rp); Inc(Sp); end; SetLength(Result, Rp - PAnsiChar(Result)); end;I will not enter in much detail about the implementation, but I think it is quite simple, and it uses the same approach used in the previous post.
The results
Again, I did a simple benchmark application so I could see if there is some gain using this new method.Original code: 5.10 seconds
Modified code: 0.82 seconds
for 1,000,000 function calls. Quite impressive, isn't it? Of course, this benchmark used a specific string, and a different string will give different results.
This time, the new method is more than 6 times faster than the original method, in a single thread. I suspect, based on my previous post about String concatenation in Delphi, that the new code can be even faster - and more multi-core friendly - in a multi-threaded application (like IW applications). I will create this benchmark application and write a blog post about the results soon.
Checking one of my IW applications, I've found forms with more than 100 hidden fields in it. The time gain will be insignificant (less than 1 millisecond), but this is not the point. The main point when I try to make my applications faster, specially Intraweb applications, is: make it run as fast as you can AND make it more multi-core friendly.
The downloads
You can download an updated IntrawebPatch.pas unit containing this new patch (and the old ones) here.Enjoy!
3 comments:
I Alexander, very interesting article!
I have tried your code, but i can't compile my Intraweb project including these units...
(I have IW10, with Delphi 2010).
[RtlVclOptimize.pas] - error at this line:
LocaleOverride[sizeof(LocaleOverride) - 1] := #0;
[DCC Error] RtlVclOptimize.pas(3298): E1012 Constant expression violates subrange bounds
-----------
[IntrawebPatch.pas] - error at this line
Function TIWBaseFormHack.TextToHTMLStringLiteral(aText: string): string;
-->
[DCC Error] IntrawebPatch.pas(171): E2010 Incompatible types: 'AnsiChar' and 'Char'
Any suggestions?
Hi Danilo,
I didn't check Delphi 2010 compatibility before releasing the code, sorry. I saw today that Andreas Hausladen's RtlVclOptimize.pas has various incompatibilities with more recent versions of Delphi. I'm creating a new patch, independent from RtlVclOptimize.pas. I will post the new code today.
Best regards
Hi, and thank you very much for the quick response!
There are really interesting ideas in this blog!
Post a Comment