gcs_filter.cpp raw

   1  // Copyright (c) 2018-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 <bench/bench.h>
   6  #include <blockfilter.h>
   7  #include <uint256.h>
   8  
   9  #include <cstdint>
  10  #include <utility>
  11  #include <vector>
  12  
  13  static GCSFilter::ElementSet GenerateGCSTestElements()
  14  {
  15      GCSFilter::ElementSet elements;
  16  
  17      // Testing the benchmarks with different number of elements show that a filter
  18      // with at least 100,000 elements results in benchmarks that have the same
  19      // ns/op. This makes it easy to reason about how long (in nanoseconds) a single
  20      // filter element takes to process.
  21      for (int i = 0; i < 100000; ++i) {
  22          GCSFilter::Element element(32);
  23          element[0] = static_cast<unsigned char>(i);
  24          element[1] = static_cast<unsigned char>(i >> 8);
  25          elements.insert(std::move(element));
  26      }
  27  
  28      return elements;
  29  }
  30  
  31  static void GCSBlockFilterGetHash(benchmark::Bench& bench)
  32  {
  33      auto elements = GenerateGCSTestElements();
  34  
  35      GCSFilter filter({0, 0, BASIC_FILTER_P, BASIC_FILTER_M}, elements);
  36      BlockFilter block_filter(BlockFilterType::BASIC, {}, filter.GetEncoded(), /*skip_decode_check=*/false);
  37  
  38      bench.run([&] {
  39          block_filter.GetHash();
  40      });
  41  }
  42  
  43  static void GCSFilterConstruct(benchmark::Bench& bench)
  44  {
  45      auto elements = GenerateGCSTestElements();
  46  
  47      uint64_t siphash_k0 = 0;
  48      bench.run([&]{
  49          GCSFilter filter({siphash_k0, 0, BASIC_FILTER_P, BASIC_FILTER_M}, elements);
  50  
  51          siphash_k0++;
  52      });
  53  }
  54  
  55  static void GCSFilterDecode(benchmark::Bench& bench)
  56  {
  57      auto elements = GenerateGCSTestElements();
  58  
  59      GCSFilter filter({0, 0, BASIC_FILTER_P, BASIC_FILTER_M}, elements);
  60      auto encoded = filter.GetEncoded();
  61  
  62      bench.run([&] {
  63          GCSFilter filter({0, 0, BASIC_FILTER_P, BASIC_FILTER_M}, encoded, /*skip_decode_check=*/false);
  64      });
  65  }
  66  
  67  static void GCSFilterDecodeSkipCheck(benchmark::Bench& bench)
  68  {
  69      auto elements = GenerateGCSTestElements();
  70  
  71      GCSFilter filter({0, 0, BASIC_FILTER_P, BASIC_FILTER_M}, elements);
  72      auto encoded = filter.GetEncoded();
  73  
  74      bench.run([&] {
  75          GCSFilter filter({0, 0, BASIC_FILTER_P, BASIC_FILTER_M}, encoded, /*skip_decode_check=*/true);
  76      });
  77  }
  78  
  79  static void GCSFilterMatch(benchmark::Bench& bench)
  80  {
  81      auto elements = GenerateGCSTestElements();
  82  
  83      GCSFilter filter({0, 0, BASIC_FILTER_P, BASIC_FILTER_M}, elements);
  84  
  85      bench.run([&] {
  86          filter.Match(GCSFilter::Element());
  87      });
  88  }
  89  BENCHMARK(GCSBlockFilterGetHash);
  90  BENCHMARK(GCSFilterConstruct);
  91  BENCHMARK(GCSFilterDecode);
  92  BENCHMARK(GCSFilterDecodeSkipCheck);
  93  BENCHMARK(GCSFilterMatch);
  94