xref: /llvm-project/libcxx/test/benchmarks/stringstream.bench.cpp (revision b2d2494731976ab7aa9702f3134472db694b9332)
16a54dfbfSLouis Dionne //===----------------------------------------------------------------------===//
26a54dfbfSLouis Dionne //
36a54dfbfSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
46a54dfbfSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
56a54dfbfSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66a54dfbfSLouis Dionne //
76a54dfbfSLouis Dionne //===----------------------------------------------------------------------===//
86a54dfbfSLouis Dionne 
9*b2d24947SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
10*b2d24947SLouis Dionne 
1178b4b5ccSLouis Dionne #include "benchmark/benchmark.h"
1278b4b5ccSLouis Dionne #include "test_macros.h"
1378b4b5ccSLouis Dionne 
1478b4b5ccSLouis Dionne #include <mutex>
1578b4b5ccSLouis Dionne #include <sstream>
1678b4b5ccSLouis Dionne 
1778b4b5ccSLouis Dionne TEST_NOINLINE double istream_numbers();
1878b4b5ccSLouis Dionne 
1978b4b5ccSLouis Dionne double istream_numbers(std::locale* loc) {
2078b4b5ccSLouis Dionne   const char* a[] = {"-6  69 -71  2.4882e-02 -100 101 -2.00005 5000000 -50000000",
2178b4b5ccSLouis Dionne                      "-25 71   7 -9.3262e+01 -100 101 -2.00005 5000000 -50000000",
2278b4b5ccSLouis Dionne                      "-14 53  46 -6.7026e-02 -100 101 -2.00005 5000000 -50000000"};
2378b4b5ccSLouis Dionne 
2478b4b5ccSLouis Dionne   int a1, a2, a3, a4, a5, a6, a7;
2578b4b5ccSLouis Dionne   double f1 = 0.0, f2 = 0.0, q = 0.0;
2678b4b5ccSLouis Dionne   for (int i = 0; i < 3; i++) {
2778b4b5ccSLouis Dionne     std::istringstream s(a[i]);
2878b4b5ccSLouis Dionne     if (loc)
2978b4b5ccSLouis Dionne       s.imbue(*loc);
3078b4b5ccSLouis Dionne     s >> a1 >> a2 >> a3 >> f1 >> a4 >> a5 >> f2 >> a6 >> a7;
3178b4b5ccSLouis Dionne     q += (a1 + a2 + a3 + a4 + a5 + a6 + a7 + f1 + f2) / 1000000;
3278b4b5ccSLouis Dionne   }
3378b4b5ccSLouis Dionne   return q;
3478b4b5ccSLouis Dionne }
3578b4b5ccSLouis Dionne 
3678b4b5ccSLouis Dionne struct LocaleSelector {
3778b4b5ccSLouis Dionne   std::locale* imbue;
3878b4b5ccSLouis Dionne   std::locale old;
3978b4b5ccSLouis Dionne   static std::mutex mutex;
4078b4b5ccSLouis Dionne 
4178b4b5ccSLouis Dionne   LocaleSelector(benchmark::State& state) {
4278b4b5ccSLouis Dionne     std::lock_guard guard(mutex);
4378b4b5ccSLouis Dionne     switch (state.range(0)) {
4478b4b5ccSLouis Dionne     case 0: {
4578b4b5ccSLouis Dionne       old   = std::locale::global(std::locale::classic());
4678b4b5ccSLouis Dionne       imbue = nullptr;
4778b4b5ccSLouis Dionne       break;
4878b4b5ccSLouis Dionne     }
4978b4b5ccSLouis Dionne     case 1: {
5078b4b5ccSLouis Dionne       old = std::locale::global(std::locale::classic());
5178b4b5ccSLouis Dionne       thread_local std::locale loc("en_US.UTF-8");
5278b4b5ccSLouis Dionne       imbue = &loc;
5378b4b5ccSLouis Dionne       break;
5478b4b5ccSLouis Dionne     }
5578b4b5ccSLouis Dionne     case 2: {
5678b4b5ccSLouis Dionne       old = std::locale::global(std::locale::classic());
5778b4b5ccSLouis Dionne       static std::locale loc("en_US.UTF-8");
5878b4b5ccSLouis Dionne       imbue = &loc;
5978b4b5ccSLouis Dionne       break;
6078b4b5ccSLouis Dionne     }
6178b4b5ccSLouis Dionne     case 3: {
6278b4b5ccSLouis Dionne       old   = std::locale::global(std::locale("en_US.UTF-8"));
6378b4b5ccSLouis Dionne       imbue = nullptr;
6478b4b5ccSLouis Dionne       break;
6578b4b5ccSLouis Dionne     }
6678b4b5ccSLouis Dionne     }
6778b4b5ccSLouis Dionne   }
6878b4b5ccSLouis Dionne 
6978b4b5ccSLouis Dionne   ~LocaleSelector() {
7078b4b5ccSLouis Dionne     std::lock_guard guard(mutex);
7178b4b5ccSLouis Dionne     std::locale::global(old);
7278b4b5ccSLouis Dionne   }
7378b4b5ccSLouis Dionne };
7478b4b5ccSLouis Dionne 
7578b4b5ccSLouis Dionne std::mutex LocaleSelector::mutex;
7678b4b5ccSLouis Dionne 
7778b4b5ccSLouis Dionne static void BM_Istream_numbers(benchmark::State& state) {
7878b4b5ccSLouis Dionne   LocaleSelector sel(state);
7978b4b5ccSLouis Dionne   double i = 0;
8078b4b5ccSLouis Dionne   while (state.KeepRunning())
8178b4b5ccSLouis Dionne     benchmark::DoNotOptimize(i += istream_numbers(sel.imbue));
8278b4b5ccSLouis Dionne }
8378b4b5ccSLouis Dionne BENCHMARK(BM_Istream_numbers)->DenseRange(0, 3)->UseRealTime()->Threads(1)->ThreadPerCpu();
8478b4b5ccSLouis Dionne 
8578b4b5ccSLouis Dionne static void BM_Ostream_number(benchmark::State& state) {
8678b4b5ccSLouis Dionne   LocaleSelector sel(state);
8778b4b5ccSLouis Dionne   while (state.KeepRunning()) {
8878b4b5ccSLouis Dionne     std::ostringstream ss;
8978b4b5ccSLouis Dionne     if (sel.imbue)
9078b4b5ccSLouis Dionne       ss.imbue(*sel.imbue);
9178b4b5ccSLouis Dionne     ss << 0;
9278b4b5ccSLouis Dionne     benchmark::DoNotOptimize(ss.str().c_str());
9378b4b5ccSLouis Dionne   }
9478b4b5ccSLouis Dionne }
9578b4b5ccSLouis Dionne BENCHMARK(BM_Ostream_number)->DenseRange(0, 3)->UseRealTime()->Threads(1)->ThreadPerCpu();
9678b4b5ccSLouis Dionne 
9778b4b5ccSLouis Dionne BENCHMARK_MAIN();
98