blob: ebb8d7dd2779978b486bc2b4ecc962ff980961e4 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
**/
#include <cstddef>
#include <ctime>
#include <random>
#include <vector>
#include "types/port/TypesPortConfig.h"
#include "types/port/timegm.hpp"
#include "benchmark/benchmark.h"
namespace quickstep {
namespace {
static constexpr std::size_t kNumSamples = 100;
static constexpr std::size_t kMaxThreads = 8;
// Initialize random valid values of broken-time structs.
template <typename TM>
void PreInitSamples(const std::size_t num_samples, std::vector<TM> *times) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> year(0, 100);
std::uniform_int_distribution<> month(0, 11);
std::uniform_int_distribution<> day(1, 28);
std::uniform_int_distribution<> hours(0, 23);
std::uniform_int_distribution<> min_sec(0, 59);
TM time = {};
for (std::size_t i = 0; i < num_samples; ++i) {
time.tm_year = year(gen);
time.tm_mon = month(gen);
time.tm_mday = day(gen);
time.tm_hour = hours(gen);
time.tm_min = min_sec(gen);
time.tm_sec = min_sec(gen);
times->push_back(time);
}
}
} // namespace
// Benchmark mktime().
static void BM_mktime(benchmark::State &state) { // NOLINT(runtime/references)
state.PauseTiming();
std::vector<std::tm> times;
PreInitSamples(kNumSamples, &times);
state.ResumeTiming();
std::size_t i = 0;
std::time_t time BENCHMARK_UNUSED;
while (state.KeepRunning()) {
time = std::mktime(&times[i]);
if (++i == kNumSamples) {
i = 0;
}
}
}
BENCHMARK(BM_mktime)->ThreadRange(1, kMaxThreads);
#if defined(QUICKSTEP_HAVE_TIMEGM)
// Benchmark system timegm().
static void BM_timegmWithOriginal(benchmark::State &state) { // NOLINT(runtime/references)
state.PauseTiming();
std::vector<struct tm> times;
PreInitSamples(kNumSamples, &times);
state.ResumeTiming();
std::size_t i = 0;
std::time_t time BENCHMARK_UNUSED;
while (state.KeepRunning()) {
time = timegmWithOriginal(&times[i]);
if (++i == kNumSamples) {
i = 0;
}
}
}
BENCHMARK(BM_timegmWithOriginal)->ThreadRange(1, kMaxThreads);
#endif // defined(QUICKSTEP_HAVE_TIMEGM)
#if defined(QUICKSTEP_HAVE_SETENV) && defined(QUICKSTEP_HAVE_TZSET)
// Benchmark custom timegm() implementation using tzset() and mktime().
static void BM_timegmWithTZGMT(benchmark::State &state) { // NOLINT(runtime/references)
state.PauseTiming();
std::vector<struct tm> times;
PreInitSamples(kNumSamples, &times);
state.ResumeTiming();
std::size_t i = 0;
std::time_t time BENCHMARK_UNUSED;
while (state.KeepRunning()) {
time = timegmWithTZGMT(&times[i]);
if (++i == kNumSamples) {
i = 0;
}
}
}
BENCHMARK(BM_timegmWithTZGMT)->ThreadRange(1, kMaxThreads);
#endif // defined(QUICKSTEP_HAVE_SETENV) && defined(QUICKSTEP_HAVE_TZSET)
// Benchmark custom timegm() implementation using precomputed timezone offsets.
static void BM_timegmWithPrecomputedOffset(benchmark::State &state) { // NOLINT(runtime/references)
state.PauseTiming();
std::vector<struct tm> times;
PreInitSamples(kNumSamples, &times);
state.ResumeTiming();
std::size_t i = 0;
std::time_t time BENCHMARK_UNUSED;
while (state.KeepRunning()) {
time = timegmWithPrecomputedOffset(&times[i]);
if (++i == kNumSamples) {
i = 0;
}
}
}
BENCHMARK(BM_timegmWithPrecomputedOffset)->ThreadRange(1, kMaxThreads);
// Benchmark custom timegm() implementation.
static void BM_timegmCustom(benchmark::State &state) { // NOLINT(runtime/references)
state.PauseTiming();
std::vector<struct tm> times;
PreInitSamples(kNumSamples, &times);
state.ResumeTiming();
std::size_t i = 0;
std::time_t time BENCHMARK_UNUSED;
while (state.KeepRunning()) {
time = timegmCustom(&times[i]);
if (++i == kNumSamples) {
i = 0;
}
}
}
BENCHMARK(BM_timegmCustom)->ThreadRange(1, kMaxThreads);
} // namespace quickstep
int main(int argc, char **argv) {
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
return 0;
}