Split&Join String - Abseil vs RangeV3 vs Boost vs CustomImpl
#include " Bench.hpp"
#include < base/stl/String.hpp>
#include < base/stl/Vector.hpp>
#include < sstream>
#include < boost/algorithm/string.hpp>
#include < range/v3/view/join.hpp>
#include < range/v3/view/split.hpp>
#include < absl/strings/str_join.h>
#include < absl/strings/str_split.h>
namespace detail
{
// / A test string to test split method.
const base::String splitTestStr = " one,two,three,four,five,six,seven,eight,nine,ten" ;
// / A test list of strings to test join method.
const base::Vector<base::String> joinTestStr = {
" one" , " two" , " three" , " four" , " five" , " six" , " seven" , " eight" , " nine" , " ten"
};
base::Vector<base::String> SplitStlVer (const base::String& str, const char delimiter = ' ,' )
{
base::Vector<base::String> result;
std::stringstream input{ str };
base::String item;
while (std::getline (input, item, delimiter)) {
if (item.size ()) {
result.emplace_back (std::move (item));
}
}
if (std::getline (input, item, static_cast <char >(EOF)) && item.size ()) {
result.emplace_back (std::move (item));
}
return result;
}
base::String JoinStlVer (base::Vector<base::String> list, const char delimeter = ' ,' )
{
std::string str;
if (list.empty ()) {
return str;
}
std::for_each (list.begin (), list.end (), [&](base::StringView s) {
if (!str.empty ()) {
str += delimeter;
}
str += s;
});
return str;
}
} // namespace detail
void SplitStrStlVer (bench::State& state)
{
auto split = []{
return detail::SplitStlVer (detail::splitTestStr);
};
assert (split () == detail::joinTestStr);
for (auto _ : state) {
const auto result = split ();
bench::DoNotOptimize (result);
}
}
BENCH (SplitStrStlVer);
void SplitStrBoostVer (bench::State& state)
{
auto split = []{
base::Vector<base::String> result;
boost::split (result, detail::splitTestStr, boost::is_any_of (" ," ));
return result;
};
assert (split () == detail::joinTestStr);
for (auto _ : state) {
const auto result = split ();
bench::DoNotOptimize (result);
}
}
BENCH (SplitStrBoostVer);
void SplitStrRangesV3Ver (bench::State& state)
{
auto split = []() {
return ranges::view::split (detail::splitTestStr, ' ,' );
};
base::Vector<base::String> list = split ();
assert (list == detail::joinTestStr);
for (auto _ : state) {
const auto result = split ();
bench::DoNotOptimize (result);
}
}
BENCH (SplitStrRangesV3Ver);
void SplitStrAbseilVer (bench::State& state)
{
auto split = []{
return absl::StrSplit (detail::splitTestStr, " ," );
};
base::Vector<base::String> list = split ();
assert (list == detail::joinTestStr);
for (auto _ : state) {
const auto result = split ();
bench::DoNotOptimize (result);
}
}
BENCH (SplitStrAbseilVer);
void JoinStrStlVer (bench::State& state)
{
auto join = [] {
return detail::JoinStlVer (detail::joinTestStr);
};
assert (join () == detail::splitTestStr);
for (auto _ : state) {
const auto result = join ();
bench::DoNotOptimize (result);
}
}
BENCH (JoinStrStlVer);
void JoinStrBoostVer (bench::State& state)
{
auto join = [] {
return boost::algorithm::join (detail::joinTestStr, " ," );
};
assert (join () == detail::splitTestStr);
for (auto _ : state) {
const auto result = join ();
bench::DoNotOptimize (result);
}
}
BENCH (JoinStrBoostVer);
void JoinStrRangesV3Ver (bench::State& state)
{
auto join = [] {
return ranges::view::join (detail::joinTestStr, ' ,' );
};
const base::String str = join ();
assert (str == detail::splitTestStr);
for (auto _ : state) {
const auto result = join ();
bench::DoNotOptimize (result);
}
}
BENCH (JoinStrRangesV3Ver);
void JoinStrAbseilVer (bench::State& state)
{
auto join = [] {
return absl::StrJoin (detail::joinTestStr, " ," );
};
const base::String str = join ();
assert (str == detail::splitTestStr);
for (auto _ : state) {
const auto result = join ();
bench::DoNotOptimize (result);
}
}
BENCH (JoinStrAbseilVer);
Run on (8 X 2300 MHz CPU s)
CPU Caches:
L1 Data 32K (x4)
L1 Instruction 32K (x4)
L2 Unified 262K (x4)
L3 Unified 6291K (x1)
*** WARNING*** Library was built as DEBUG. Timings may be affected.
----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------------------
SplitStrStlVer/iterations:1000000 5582 ns 5489 ns 1000000
SplitStrBoostVer/iterations:1000000 8583 ns 8570 ns 1000000
SplitStrRangesV3Ver/iterations:1000000 104 ns 104 ns 1000000
SplitStrAbseilVer/iterations:1000000 171 ns 171 ns 1000000
JoinStrStlVer/iterations:1000000 1019 ns 1019 ns 1000000
JoinStrBoostVer/iterations:1000000 3213 ns 3207 ns 1000000
JoinStrRangesV3Ver/iterations:1000000 130 ns 130 ns 1000000
JoinStrAbseilVer/iterations:1000000 554 ns 554 ns 1000000
auto -> base::Vector< base::String > for split
auto -> base::String for join
Run on (8 X 2300 MHz CPU s)
CPU Caches:
L1 Data 32K (x4)
L1 Instruction 32K (x4)
L2 Unified 262K (x4)
L3 Unified 6291K (x1)
*** WARNING*** Library was built as DEBUG. Timings may be affected.
----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------------------
SplitStrStlVer/iterations:1000000 4398 ns 4393 ns 1000000
SplitStrBoostVer/iterations:1000000 8568 ns 8558 ns 1000000
SplitStrRangesV3Ver/iterations:1000000 64349 ns 64287 ns 1000000
SplitStrAbseilVer/iterations:1000000 1954 ns 1953 ns 1000000
JoinStrStlVer/iterations:1000000 1018 ns 1017 ns 1000000
JoinStrBoostVer/iterations:1000000 3128 ns 3126 ns 1000000
JoinStrRangesV3Ver/iterations:1000000 24593 ns 24576 ns 1000000
JoinStrAbseilVer/iterations:1000000 543 ns 543 ns 1000000
Run on (8 X 2300 MHz CPU s)
CPU Caches:
L1 Data 32K (x4)
L1 Instruction 32K (x4)
L2 Unified 262K (x4)
L3 Unified 6291K (x1)
----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------------------
SplitStrStlVer/iterations:1000000 1104 ns 1103 ns 1000000
SplitStrBoostVer/iterations:1000000 1184 ns 1183 ns 1000000
SplitStrRangesV3Ver/iterations:1000000 1064 ns 1063 ns 1000000
SplitStrAbseilVer/iterations:1000000 378 ns 377 ns 1000000
JoinStrStlVer/iterations:1000000 448 ns 447 ns 1000000
JoinStrBoostVer/iterations:1000000 374 ns 373 ns 1000000
JoinStrRangesV3Ver/iterations:1000000 448 ns 448 ns 1000000
JoinStrAbseilVer/iterations:1000000 155 ns 155 ns 1000000