| 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);
|
|---|