From 39960ccef14230d7d72eac8efd993cc5d3dae390 Mon Sep 17 00:00:00 2001 From: Martchus Date: Fri, 27 Jan 2017 22:14:12 +0100 Subject: [PATCH] Add simple benachmark for string builder --- tests/stringbuilder-bench.cpp | 65 +++++++++++++++++++++++++++++++++++ tests/stringbuilder-bench.md | 51 +++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tests/stringbuilder-bench.cpp create mode 100644 tests/stringbuilder-bench.md diff --git a/tests/stringbuilder-bench.cpp b/tests/stringbuilder-bench.cpp new file mode 100644 index 0000000..3a1115c --- /dev/null +++ b/tests/stringbuilder-bench.cpp @@ -0,0 +1,65 @@ +#include "../conversion/stringbuilder.h" +#include "../conversion/stringconversion.h" +#include "../chrono/datetime.h" + +#include +#include +#include + +using namespace std; +using namespace ConversionUtilities; +using namespace ChronoUtilities; + +int main() +{ + cout << "Benchmarking string builder vs. stringstream" << endl; + + constexpr unsigned int iterations = 500000; + constexpr unsigned int iterations2 = 50; + + vector v1, v2; + v1.reserve(iterations); + v2.reserve(iterations); + + DateTime t1 = DateTime::now(); + for(unsigned int r = 0; r < iterations2; ++r) { + for(unsigned int i = 0; i < iterations; ++i) { + stringstream ss; + v1.emplace_back("left. " + numberToString(i + 1) + "; right: " + numberToString(i + 2) + "; top: " + numberToString(i + 3) + "; bottom: " + numberToString(i + 4) + ';'); + } + v1.clear(); + } + DateTime t2 = DateTime::now(); + cout << "plus operator: " << (t2 - t1).toString(TimeSpanOutputFormat::Normal, true) << endl; + + t1 = DateTime::now(); + for(unsigned int r = 0; r < iterations2; ++r) { + for(unsigned int i = 0; i < iterations; ++i) { + stringstream ss; + ss << "left: " << (i + 1) << "; right: " << (i + 2) << "; top: " << (i + 3) << "; bottom: " << (i + 4) << ';'; + v1.emplace_back(ss.str()); + } + v1.clear(); + } + t2 = DateTime::now(); + const TimeSpan diff1 = t2 - t1; + cout << "stringstream: " << diff1.toString(TimeSpanOutputFormat::Normal, true) << endl; + + t1 = DateTime::now(); + for(unsigned int r = 0; r < iterations2; ++r) { + for(unsigned int i = 0; i < iterations; ++i) { + v2.emplace_back("left. " % numberToString(i + 1) % "; right: " % numberToString(i + 2) % "; top: " % numberToString(i + 3) % "; bottom: " % numberToString(i + 4) + ';'); + } + v2.clear(); + } + t2 = DateTime::now(); + const TimeSpan diff2 = t2 - t1; + cout << "string builder: " << diff2.toString(TimeSpanOutputFormat::Normal, true) << endl; + + v1.swap(v2); + + cout << "diff (stringstream minus string builder): " << (diff1 - diff2).toString(TimeSpanOutputFormat::Normal, true) << endl; + cout << "factor (stringstream / string builder): " << (static_cast(diff1.totalTicks()) / diff2.totalTicks()) << endl; + + return 0; +} diff --git a/tests/stringbuilder-bench.md b/tests/stringbuilder-bench.md new file mode 100644 index 0000000..641f2d1 --- /dev/null +++ b/tests/stringbuilder-bench.md @@ -0,0 +1,51 @@ +# Simple/stupid benchmarking + +Compares the string builder and numberToString() function as provided by c++utilities +with std::stringstream (without reserving stringstream buffer). + +The string builder is actually just a fancy syntax for std::string::reserve() +making its use more convenient. + +## Compile and run + +eg. +``` +g++ -O3 stringbuilder-bench.cpp -o stringbuilder-bench-O3 -Wl,-rpath /lib/path -L /lib/path -lc++utilities +./stringbuilder-bench-O3 +``` + +## Results on my machine + +Results with -03: + +``` +plus operator: 00:00:17 +stringstream: 00:00:16 +string builder: 00:00:07 +diff (stringstream minus string builder): 00:00:09 +factor (stringstream / string builder): 2.28571 +``` + +However, with -O0 4 times *slower*: + +``` +plus operator: 00:00:29 +stringstream: 00:00:16 +string builder: 00:01:04 +diff (stringstream minus string builder): - 00:35:22 +factor (stringstream / string builder): 0.25 +``` + +Still 1.45 times faster than stringstream with -O2: + +``` +plus operator: 00:00:21 +stringstream: 00:00:16 +string builder: 00:00:11 +diff (stringstream minus string builder): 00:00:05 +factor (stringstream / string builder): 1.45455 +``` + +So this basic tests show that string builder is up to 2 times faster when using full optimization +and still 1.4 times faster when using -O2 (default under Arch Linux). However, this templating +stuff completely relies on optimization (as expected). Results with clang++ where similar.