After looking at String concatenation [1] and String Building [2] in Delphi, and as a conclusion, it’s time to have a brief look at what happens in multi-threaded settings, such as in a server pushing JSON, XML or some other text data.
Benchmark Results
The test case is the same as that of the String Building article [2], except from a multi-threaded environment.
The following graphs plots the time it takes for 1 to 8 threads to go through a given workload (100 times the 10k case), on a quad-core CPU. Lower values are better
As a reminder of the participants:
- StringBuilder is the RTL’s TStringBuilder [3] class
- Trivial is using plain String concatenation with the “:=” and “+” operators
- TTextWriter is the mORMot/Synopse [4] class (it’s the only one operating in utf-8)
- TWriteOnlyBlockStream is the DWScript [5] class from dwsUtils [6]
TStringStream is just off-the-chart, literally-speaking, it’s already beyond 2200 in the 4 threads case.
In terms of CPU usage:
- StringBuilder and Trivial cases only use one CPU, their bottlenecks are the RTL functions for String reference counting and the memory manager (Delphi-side).
- TTextWriter and TWriteOnlyBlockStream bottlenecks are found in the concatenations, integer-to-string conversions, and VirtualAlloc calls to Windows.
Interestingly enough, for both mORMot and DWScript test, the main VCL thread remained smooth and responsive during the tests, while with TStringBuilder, it was not, despite a lower overall CPU usage.
Follow this link for the source code [7].
Previous articles: