I wanted to do a certain bit of benchmarking for quite a while - years actually - but triggered by one of those friendly discussions on the ##c++ channel on FreeNode I finally figured I should sit down and actually do it. I was expecting some interesting results, but the not at the scale that we will see below.
If you ask the resident channel bot on ##c++ how to tokenize a std::string you'll get offered the following (slightly compacted) code snippet:
#include <sstream>
#include <vector>
#include <string>
std::string str("abc:def");
std::istringstream split(str);
std::vector<std ::string> tokens;
for (std::string each; std::getline(split, each, ':'); tokens.push_back(each));
Obviously, that's the "Without Qt" version: Clean Standard C++, as straight-forward as it can get. The contender "With Qt" is:
#include <QString>
#include <QStringList>
QString str("abc:def");
QStringList tokens = str.split(':');
From the source alone we can collect a few numbers:
| Property |
Without Qt |
With Qt |
Ratio |
| Code to type |
3 lines |
1 line |
3.0 |
|
147 char |
35 chars |
4.2 |
| Code usable as sub-expression |
no |
yes |
|
| Size of compilation unit [1] |
22215 lines |
7590 lines |
2.9 |
| Compile time [2] |
1.64s |
1.02s |
1.6 |
To compare performance I use a benchmark that I just checked into the Qt source base, under tests/benchmark/qstringlist. It basically consists of running the above mentioned snippets on a string "unit:unit:unit:...." with 10, 100, 1000, and 10000 "unit" chunks and record callgrind's "instruction loads per iteration" as follows:
| Chunk count |
Without Qt |
With Qt |
Ratio |
| 10 chunks |
18,455 |
9,827 |
1.9 |
| 100 chunks |
134,578 |
71,008 |
1.9 |
| 1000 chunks |
1,244,425 |
641,174 |
1.9 |
| 10000 chunks |
13,161,115 |
7,053,633 |
1.9 |
In this case, bigger numbers mean more time needed to execute. Interesting, isn't it?
After reading Thiago's latest posts I got the impression that people like conclusions. The verbose version of a conclusion might be something along the lines of
Using Qt's functions to split a string you need about a third of the effort to write code, and get a 47% performance boost at runtime.
Or shorter (Qt way): "Code less, create more".
André
[1] Counted with "g++ -E -DQT_NO_STL -I$QTDIR/include/QtCore -I$QTDIR/include qt.cpp | wc" using g++ Ubuntu 4.3.3-5ubuntu4.
[2] Fastest result of "real" time, out of 20 runs each. "user" times in both scenarios smaller, with similar ratio.