// Copyright 2017 The Abseil Authors.
//
// Licensed 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 <cstdint>
#include <cstring>

#include "benchmark/benchmark.h"
#include "absl/algorithm/algorithm.h"

namespace {

// The range of sequence sizes to benchmark.
constexpr int kMinBenchmarkSize = 1024;
constexpr int kMaxBenchmarkSize = 8 * 1024 * 1024;

// A user-defined type for use in equality benchmarks. Note that we expect
// std::memcmp to win for this type: libstdc++'s std::equal only defers to
// memcmp for integral types. This is because it is not straightforward to
// guarantee that std::memcmp would produce a result "as-if" compared by
// operator== for other types (example gotchas: NaN floats, structs with
// padding).
struct EightBits {
  explicit EightBits(int /* unused */) : data(0) {}
  bool operator==(const EightBits& rhs) const { return data == rhs.data; }
  uint8_t data;
};

template <typename T>
void BM_absl_equal_benchmark(benchmark::State& state) {
  std::vector<T> xs(state.range(0), T(0));
  std::vector<T> ys = xs;
  while (state.KeepRunning()) {
    const bool same = absl::equal(xs.begin(), xs.end(), ys.begin(), ys.end());
    benchmark::DoNotOptimize(same);
  }
}

template <typename T>
void BM_std_equal_benchmark(benchmark::State& state) {
  std::vector<T> xs(state.range(0), T(0));
  std::vector<T> ys = xs;
  while (state.KeepRunning()) {
    const bool same = std::equal(xs.begin(), xs.end(), ys.begin());
    benchmark::DoNotOptimize(same);
  }
}

template <typename T>
void BM_memcmp_benchmark(benchmark::State& state) {
  std::vector<T> xs(state.range(0), T(0));
  std::vector<T> ys = xs;
  while (state.KeepRunning()) {
    const bool same =
        std::memcmp(xs.data(), ys.data(), xs.size() * sizeof(T)) == 0;
    benchmark::DoNotOptimize(same);
  }
}

// The expectation is that the compiler should be able to elide the equality
// comparison altogether for sufficiently simple types.
template <typename T>
void BM_absl_equal_self_benchmark(benchmark::State& state) {
  std::vector<T> xs(state.range(0), T(0));
  while (state.KeepRunning()) {
    const bool same = absl::equal(xs.begin(), xs.end(), xs.begin(), xs.end());
    benchmark::DoNotOptimize(same);
  }
}

BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint8_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint8_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint8_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint8_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);

BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint16_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint16_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint16_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint16_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);

BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint32_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint32_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint32_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint32_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);

BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint64_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint64_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint64_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint64_t)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);

BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, EightBits)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_std_equal_benchmark, EightBits)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_memcmp_benchmark, EightBits)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);
BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, EightBits)
    ->Range(kMinBenchmarkSize, kMaxBenchmarkSize);

}  // namespace
