1 | /*
|
---|
2 | c++ -std=c++1z -pedantic -Wall -Wextra -O3 -lbenchmark -lbenchmark_main -I. -I./src -I../src -I.. -o benchmark-encode_length.2 ./benchmark-encode_length.2.cc && ./benchmark-encode_length.2
|
---|
3 | */
|
---|
4 | #include <limits>
|
---|
5 |
|
---|
6 | #include "benchmark/benchmark.h"
|
---|
7 |
|
---|
8 |
|
---|
9 | template<class T>
|
---|
10 | std::string
|
---|
11 | encode_length_original(T len)
|
---|
12 | {
|
---|
13 | std::string result;
|
---|
14 | if (len < 255) {
|
---|
15 | result += static_cast<unsigned char>(len);
|
---|
16 | } else {
|
---|
17 | result += '\xff';
|
---|
18 | len -= 255;
|
---|
19 | while (true) {
|
---|
20 | unsigned char b = static_cast<unsigned char>(len & 0x7f);
|
---|
21 | len >>= 7;
|
---|
22 | if (!len) {
|
---|
23 | result += char(b | static_cast<unsigned char>(0x80));
|
---|
24 | break;
|
---|
25 | }
|
---|
26 | result += b;
|
---|
27 | }
|
---|
28 | }
|
---|
29 | return result;
|
---|
30 | }
|
---|
31 |
|
---|
32 | const unsigned long long x = 0xff;
|
---|
33 | //const unsigned long long x = std::numeric_limits<unsigned long>::max() - 10;
|
---|
34 | static void BM_EncodeLength_Original(benchmark::State& state) {
|
---|
35 | for (auto _ : state) {
|
---|
36 | std::string s;
|
---|
37 | for (auto i = x; i != 0; i >>= 1) {
|
---|
38 | s += encode_length_original(i);
|
---|
39 | }
|
---|
40 | }
|
---|
41 | }
|
---|
42 | BENCHMARK(BM_EncodeLength_Original);
|
---|
43 |
|
---|
44 |
|
---|
45 | template<class T>
|
---|
46 | std::string
|
---|
47 | encode_length_optimized(T len)
|
---|
48 | {
|
---|
49 | std::string result;
|
---|
50 | if (len < 255) {
|
---|
51 | result += static_cast<unsigned char>(len);
|
---|
52 | return result;
|
---|
53 | } else {
|
---|
54 | result += '\xff';
|
---|
55 | len -= 255;
|
---|
56 | while (true) {
|
---|
57 | unsigned char b = static_cast<unsigned char>(len & 0x7f);
|
---|
58 | len >>= 7;
|
---|
59 | if (!len) {
|
---|
60 | result += b | static_cast<unsigned char>(0x80);
|
---|
61 | break;
|
---|
62 | }
|
---|
63 | result += b;
|
---|
64 | }
|
---|
65 | return result;
|
---|
66 | }
|
---|
67 | }
|
---|
68 | static void BM_EncodeLength_Optimized(benchmark::State& state) {
|
---|
69 | for (auto _ : state) {
|
---|
70 | std::string s;
|
---|
71 | for (auto i = x; i != 0; i >>= 1) {
|
---|
72 | s += encode_length_optimized(i);
|
---|
73 | }
|
---|
74 | }
|
---|
75 | }
|
---|
76 | BENCHMARK(BM_EncodeLength_Optimized);
|
---|
77 |
|
---|
78 |
|
---|
79 | template<class U>
|
---|
80 | inline void
|
---|
81 | pack_uint(std::string & s, U value)
|
---|
82 | {
|
---|
83 | static_assert(std::is_unsigned<U>::value, "Unsigned type required");
|
---|
84 |
|
---|
85 | while (value >= 128) {
|
---|
86 | s += static_cast<char>(static_cast<unsigned char>(value) | 0x80);
|
---|
87 | value >>= 7;
|
---|
88 | }
|
---|
89 | s += static_cast<char>(value);
|
---|
90 | }
|
---|
91 | static void BM_EncodeLength_Pack(benchmark::State& state) {
|
---|
92 | for (auto _ : state) {
|
---|
93 | std::string s;
|
---|
94 | for (auto i = x; i != 0; i >>= 1) {
|
---|
95 | pack_uint(s, i);
|
---|
96 | }
|
---|
97 | }
|
---|
98 | }
|
---|
99 | BENCHMARK(BM_EncodeLength_Pack);
|
---|
100 |
|
---|
101 |
|
---|
102 | inline void
|
---|
103 | pack_char(std::string & s, char value)
|
---|
104 | {
|
---|
105 | s += value;
|
---|
106 | }
|
---|
107 | static void BM_EncodeLength_Char(benchmark::State& state) {
|
---|
108 | for (auto _ : state) {
|
---|
109 | std::string s;
|
---|
110 | for (auto i = x; i != 0; i >>= 1) {
|
---|
111 | pack_char(s, i);
|
---|
112 | }
|
---|
113 | }
|
---|
114 | }
|
---|
115 | BENCHMARK(BM_EncodeLength_Char);
|
---|