/ src / bench / prevector.cpp
prevector.cpp
  1  // Copyright (c) 2015-2022 The Bitcoin Core developers
  2  // Distributed under the MIT software license, see the accompanying
  3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4  
  5  #include <prevector.h>
  6  
  7  #include <bench/bench.h>
  8  #include <script/script.h>
  9  #include <serialize.h>
 10  #include <streams.h>
 11  
 12  #include <type_traits>
 13  #include <vector>
 14  
 15  struct nontrivial_t
 16  {
 17      int x{-1};
 18      nontrivial_t() = default;
 19      SERIALIZE_METHODS(nontrivial_t, obj) { READWRITE(obj.x); }
 20  };
 21  
 22  static_assert(!std::is_trivially_default_constructible_v<nontrivial_t>,
 23                "expected nontrivial_t to not be trivially constructible");
 24  
 25  typedef unsigned char trivial_t;
 26  static_assert(std::is_trivially_default_constructible_v<trivial_t>,
 27                "expected trivial_t to be trivially constructible");
 28  
 29  template <typename T>
 30  static void PrevectorDestructor(benchmark::Bench& bench)
 31  {
 32      bench.batch(2).run([&] {
 33          prevector<CScriptBase::STATIC_SIZE, T> t0;
 34          prevector<CScriptBase::STATIC_SIZE, T> t1;
 35          t0.resize(CScriptBase::STATIC_SIZE);
 36          t1.resize(CScriptBase::STATIC_SIZE + 1);
 37      });
 38  }
 39  
 40  template <typename T>
 41  static void PrevectorClear(benchmark::Bench& bench)
 42  {
 43      prevector<CScriptBase::STATIC_SIZE, T> t0;
 44      prevector<CScriptBase::STATIC_SIZE, T> t1;
 45      bench.batch(2).run([&] {
 46          t0.resize(CScriptBase::STATIC_SIZE);
 47          t0.clear();
 48          t1.resize(CScriptBase::STATIC_SIZE + 1);
 49          t1.clear();
 50      });
 51  }
 52  
 53  template <typename T>
 54  static void PrevectorResize(benchmark::Bench& bench)
 55  {
 56      prevector<CScriptBase::STATIC_SIZE, T> t0;
 57      prevector<CScriptBase::STATIC_SIZE, T> t1;
 58      bench.batch(4).run([&] {
 59          t0.resize(CScriptBase::STATIC_SIZE);
 60          t0.resize(0);
 61          t1.resize(CScriptBase::STATIC_SIZE + 1);
 62          t1.resize(0);
 63      });
 64  }
 65  
 66  template <typename T>
 67  static void PrevectorDeserialize(benchmark::Bench& bench)
 68  {
 69      DataStream s0{};
 70      prevector<CScriptBase::STATIC_SIZE, T> t0;
 71      t0.resize(CScriptBase::STATIC_SIZE);
 72      for (auto x = 0; x < 900; ++x) {
 73          s0 << t0;
 74      }
 75      t0.resize(100);
 76      for (auto x = 0; x < 101; ++x) {
 77          s0 << t0;
 78      }
 79      bench.batch(1000).run([&] {
 80          prevector<CScriptBase::STATIC_SIZE, T> t1;
 81          for (auto x = 0; x < 1000; ++x) {
 82              s0 >> t1;
 83          }
 84          s0.Rewind();
 85      });
 86  }
 87  
 88  template <typename T>
 89  static void PrevectorFillVectorDirect(benchmark::Bench& bench)
 90  {
 91      bench.run([&] {
 92          std::vector<prevector<CScriptBase::STATIC_SIZE, T>> vec;
 93          vec.reserve(260);
 94          for (size_t i = 0; i < 260; ++i) {
 95              vec.emplace_back();
 96          }
 97      });
 98  }
 99  
100  
101  template <typename T>
102  static void PrevectorFillVectorIndirect(benchmark::Bench& bench)
103  {
104      bench.run([&] {
105          std::vector<prevector<CScriptBase::STATIC_SIZE, T>> vec;
106          vec.reserve(260);
107          for (size_t i = 0; i < 260; ++i) {
108              // force allocation
109              vec.emplace_back(CScriptBase::STATIC_SIZE + 1, T{});
110          }
111      });
112  }
113  
114  #define PREVECTOR_TEST(name)                                         \
115      static void Prevector##name##Nontrivial(benchmark::Bench& bench) \
116      {                                                                \
117          Prevector##name<nontrivial_t>(bench);                        \
118      }                                                                \
119      BENCHMARK(Prevector##name##Nontrivial, benchmark::PriorityLevel::HIGH);         \
120      static void Prevector##name##Trivial(benchmark::Bench& bench)    \
121      {                                                                \
122          Prevector##name<trivial_t>(bench);                           \
123      }                                                                \
124      BENCHMARK(Prevector##name##Trivial, benchmark::PriorityLevel::HIGH);
125  
126  PREVECTOR_TEST(Clear)
127  PREVECTOR_TEST(Destructor)
128  PREVECTOR_TEST(Resize)
129  PREVECTOR_TEST(Deserialize)
130  PREVECTOR_TEST(FillVectorDirect)
131  PREVECTOR_TEST(FillVectorIndirect)