/ src / bench / gcs_filter.cpp
gcs_filter.cpp
 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);