range_conversion.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Range v3 library
  2. //
  3. // Copyright 2019-present Christopher Di Bella
  4. // Copyright 2019-present Eric Niebler
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. // Benchmark for https://github.com/ericniebler/range-v3/issues/1337
  14. #include <string>
  15. #include <vector>
  16. #include <benchmark/benchmark.h>
  17. #include <range/v3/algorithm/equal.hpp>
  18. #include <range/v3/range/conversion.hpp>
  19. #include <range/v3/range/primitives.hpp>
  20. #include <range/v3/view/common.hpp>
  21. #include <range/v3/view/reverse.hpp>
  22. #include <range/v3/view/transform.hpp>
  23. using namespace ranges;
  24. namespace
  25. {
  26. auto palindrome_range_common(std::vector<std::string> const & words)
  27. {
  28. auto is_palindrome = [](auto const & word) {
  29. return !ranges::empty(word) && ranges::equal(word, word | views::reverse);
  30. };
  31. auto palindrome_excalim = [&is_palindrome](auto const & word) {
  32. return is_palindrome(word) ? word + '!' : word;
  33. };
  34. auto result = words | views::transform(palindrome_excalim) | views::common;
  35. return std::vector<std::string>{ranges::begin(result), ranges::end(result)};
  36. }
  37. auto palindrome_range_to(std::vector<std::string> const & words)
  38. {
  39. auto is_palindrome = [](auto const & word) {
  40. return !ranges::empty(word) && ranges::equal(word, word | views::reverse);
  41. };
  42. auto palindrome_excalim = [&is_palindrome](auto const & word) {
  43. return is_palindrome(word) ? word + '!' : word;
  44. };
  45. return words | views::transform(palindrome_excalim) | ranges::to<std::vector>;
  46. }
  47. } // namespace
  48. class Words : public ::benchmark::Fixture
  49. {
  50. protected:
  51. std::vector<std::string> words_;
  52. public:
  53. void SetUp(const ::benchmark::State &)
  54. {
  55. auto magic = 476'000u;
  56. words_.reserve(magic);
  57. for(auto i = 0u; i < magic; ++i)
  58. {
  59. words_.push_back("this");
  60. words_.push_back("is");
  61. words_.push_back("his");
  62. words_.push_back("face");
  63. words_.push_back("abba");
  64. words_.push_back("toot");
  65. }
  66. }
  67. };
  68. BENCHMARK_F(Words, RangeCommon)(benchmark::State & st)
  69. {
  70. for(auto _ : st)
  71. {
  72. auto result = ::palindrome_range_common(words_);
  73. benchmark::DoNotOptimize(result.data());
  74. benchmark::ClobberMemory();
  75. }
  76. }
  77. BENCHMARK_F(Words, RangeTo)(benchmark::State & st)
  78. {
  79. for(auto _ : st)
  80. {
  81. auto result = ::palindrome_range_to(words_);
  82. benchmark::DoNotOptimize(result.data());
  83. benchmark::ClobberMemory();
  84. }
  85. }