prevector.cpp raw

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