Skip to content

Instantly share code, notes, and snippets.

@SlavaMelanko
Last active January 27, 2019 14:20
Show Gist options
  • Save SlavaMelanko/065cec77a5fbf114192bdd610609e05a to your computer and use it in GitHub Desktop.
Save SlavaMelanko/065cec77a5fbf114192bdd610609e05a to your computer and use it in GitHub Desktop.
test

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);

Debug

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

Release

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment