Added Raw C++ benchmarks (#6924)
authorDerek Bailey <derekbailey@google.com>
Mon, 15 Nov 2021 23:19:03 +0000 (15:19 -0800)
committerGitHub <noreply@github.com>
Mon, 15 Nov 2021 23:19:03 +0000 (15:19 -0800)
benchmarks/CMakeLists.txt
benchmarks/cpp/benchmark_main.cpp
benchmarks/cpp/flatbuffers/fb_bench.cpp
benchmarks/cpp/raw/raw_bench.cpp [new file with mode: 0644]
benchmarks/cpp/raw/raw_bench.h [new file with mode: 0644]

index d20464b..3d3032c 100644 (file)
@@ -29,15 +29,14 @@ FetchContent_MakeAvailable(
 
 set(CPP_BENCH_DIR cpp)
 set(CPP_FB_BENCH_DIR ${CPP_BENCH_DIR}/flatbuffers)
+set(CPP_RAW_BENCH_DIR ${CPP_BENCH_DIR}/raw)
 set(CPP_BENCH_FBS ${CPP_FB_BENCH_DIR}/bench.fbs)
 set(CPP_BENCH_FB_GEN ${CPP_FB_BENCH_DIR}/bench_generated.h)
 
 set(FlatBenchmark_SRCS
     ${CPP_BENCH_DIR}/benchmark_main.cpp
-    ${CPP_BENCH_DIR}/bench.h
     ${CPP_FB_BENCH_DIR}/fb_bench.cpp
-    ${CPP_FB_BENCH_DIR}/fb_bench.h
-    ${CPP_BENCH_FB_GEN}
+    ${CPP_RAW_BENCH_DIR}/raw_bench.cpp
 )
 
 # Generate the flatbuffers benchmark code from the flatbuffers schema using
index 8ace5ac..720f94e 100644 (file)
@@ -3,20 +3,48 @@
 
 #include "benchmarks/cpp/bench.h"
 #include "benchmarks/cpp/flatbuffers/fb_bench.h"
+#include "benchmarks/cpp/raw/raw_bench.h"
+
+static inline void Encode(benchmark::State &state,
+                          std::unique_ptr<Bench> &bench, uint8_t *buffer) {
+  int64_t length;
+  for (auto _ : state) {
+    bench->Encode(buffer, length);
+    benchmark::DoNotOptimize(length);
+  }
+}
+
+static inline void Decode(benchmark::State &state,
+                          std::unique_ptr<Bench> &bench, uint8_t *buffer) {
+  int64_t length;
+  uint8_t *encoded = bench->Encode(buffer, length);
+
+  for (auto _ : state) {
+    void *decoded = bench->Decode(encoded, length);
+    benchmark::DoNotOptimize(decoded);
+  }
+}
+
+static inline void Use(benchmark::State &state, std::unique_ptr<Bench> &bench,
+                       uint8_t *buffer, int64_t check_sum) {
+  int64_t length;
+  uint8_t *encoded = bench->Encode(buffer, length);
+  void *decoded = bench->Decode(encoded, length);
+
+  int64_t sum = 0;
+
+  for (auto _ : state) { sum = bench->Use(decoded); }
+
+  EXPECT_EQ(sum, check_sum);
+}
 
 static void BM_Flatbuffers_Encode(benchmark::State &state) {
   const int64_t kBufferLength = 1024;
   uint8_t buffer[kBufferLength];
 
-  int64_t length;
-
   StaticAllocator allocator(&buffer[0]);
   std::unique_ptr<Bench> bench = NewFlatBuffersBench(kBufferLength, &allocator);
-
-  for (auto _ : state) {
-    bench->Encode(buffer, length);
-    benchmark::DoNotOptimize(length);
-  }
+  Encode(state, bench, buffer);
 }
 BENCHMARK(BM_Flatbuffers_Encode);
 
@@ -24,17 +52,9 @@ static void BM_Flatbuffers_Decode(benchmark::State &state) {
   const int64_t kBufferLength = 1024;
   uint8_t buffer[kBufferLength];
 
-  int64_t length;
-
   StaticAllocator allocator(&buffer[0]);
   std::unique_ptr<Bench> bench = NewFlatBuffersBench(kBufferLength, &allocator);
-
-  uint8_t* encoded = bench->Encode(buffer, length);
-  
-  for (auto _ : state) {
-    void* decoded = bench->Decode(encoded, length);
-    benchmark::DoNotOptimize(decoded);
-  }
+  Decode(state, bench, buffer);
 }
 BENCHMARK(BM_Flatbuffers_Decode);
 
@@ -42,20 +62,35 @@ static void BM_Flatbuffers_Use(benchmark::State &state) {
   const int64_t kBufferLength = 1024;
   uint8_t buffer[kBufferLength];
 
-  int64_t length;
-
   StaticAllocator allocator(&buffer[0]);
   std::unique_ptr<Bench> bench = NewFlatBuffersBench(kBufferLength, &allocator);
+  Use(state, bench, buffer, 218812692406581874);
+}
+BENCHMARK(BM_Flatbuffers_Use);
 
-  uint8_t* encoded = bench->Encode(buffer, length);
-  void* decoded = bench->Decode(encoded, length);
+static void BM_Raw_Encode(benchmark::State &state) {
+  const int64_t kBufferLength = 1024;
+  uint8_t buffer[kBufferLength];
 
-  int64_t sum = 0;
+  std::unique_ptr<Bench> bench = NewRawBench();
+  Encode(state, bench, buffer);
+}
+BENCHMARK(BM_Raw_Encode);
 
-  for (auto _ : state) {
-    sum = bench->Use(decoded);
-  }
+static void BM_Raw_Decode(benchmark::State &state) {
+  const int64_t kBufferLength = 1024;
+  uint8_t buffer[kBufferLength];
+
+  std::unique_ptr<Bench> bench = NewRawBench();
+  Decode(state, bench, buffer);
+}
+BENCHMARK(BM_Raw_Decode);
+
+static void BM_Raw_Use(benchmark::State &state) {
+  const int64_t kBufferLength = 1024;
+  uint8_t buffer[kBufferLength];
 
-  EXPECT_EQ(sum , 218812692406581874);
+  std::unique_ptr<Bench> bench = NewRawBench();
+  Use(state, bench, buffer, 218812692406581874);
 }
-BENCHMARK(BM_Flatbuffers_Use);
\ No newline at end of file
+BENCHMARK(BM_Raw_Use);
\ No newline at end of file
index 08dc0df..2bbb9a5 100644 (file)
@@ -13,35 +13,34 @@ using namespace benchmarks_flatbuffers;
 namespace {
 
 struct FlatBufferBench : Bench {
-  explicit FlatBufferBench(int64_t initial_size,
-                           Allocator *allocator)
+  explicit FlatBufferBench(int64_t initial_size, Allocator *allocator)
       : fbb(initial_size, allocator, false) {}
 
-  uint8_t *Encode(void *, int64_t &len) override {
+  uint8_t *Encode(void *, int64_t &len) {
     fbb.Clear();
 
     const int kVectorLength = 3;
     Offset<FooBar> vec[kVectorLength];
 
-    for(int i = 0; i < kVectorLength; ++i) {
+    for (int i = 0; i < kVectorLength; ++i) {
       Foo foo(0xABADCAFEABADCAFE + i, 10000 + i, '@' + i, 1000000 + i);
       Bar bar(foo, 123456 + i, 3.14159f + i, 10000 + i);
       auto name = fbb.CreateString("Hello, World!");
-      auto foobar = CreateFooBar(fbb, &bar, name, 3.1415432432445543543 + i,
-                                 '!' + i);
+      auto foobar =
+          CreateFooBar(fbb, &bar, name, 3.1415432432445543543 + i, '!' + i);
       vec[i] = foobar;
     }
     auto location = fbb.CreateString("http://google.com/flatbuffers/");
     auto foobarvec = fbb.CreateVector(vec, kVectorLength);
-    auto foobarcontainer = CreateFooBarContainer(fbb, foobarvec, true,
-                                                 Enum_Bananas, location);
+    auto foobarcontainer =
+        CreateFooBarContainer(fbb, foobarvec, true, Enum_Bananas, location);
     fbb.Finish(foobarcontainer);
 
     len = fbb.GetSize();
     return fbb.GetBufferPointer();
   }
 
-  int64_t Use(void *decoded) override {
+  int64_t Use(void *decoded) {
     sum = 0;
     auto foobarcontainer = GetFooBarContainer(decoded);
     sum = 0;
@@ -66,7 +65,7 @@ struct FlatBufferBench : Bench {
     return sum;
   }
 
-  void *Decode(void *buffer, int64_t) override { return buffer; }
+  void *Decode(void *buffer, int64_t) { return buffer; }
   void Dealloc(void *) override{};
 
   FlatBufferBuilder fbb;
diff --git a/benchmarks/cpp/raw/raw_bench.cpp b/benchmarks/cpp/raw/raw_bench.cpp
new file mode 100644 (file)
index 0000000..810cb1f
--- /dev/null
@@ -0,0 +1,109 @@
+#include "benchmarks/cpp/raw/raw_bench.h"
+
+#include <cstdint>
+#include <cstring>
+#include <memory>
+
+#include "benchmarks/cpp/bench.h"
+
+namespace {
+const int64_t kStringLength = 32;
+const int64_t kVectorLength = 3;
+
+enum Enum { Apples, Pears, Bananas };
+
+struct Foo {
+  int64_t id;
+  short count;
+  char prefix;
+  int length;
+};
+
+struct Bar {
+  Foo parent;
+  int time;
+  float ratio;
+  unsigned short size;
+};
+
+struct FooBar {
+  Bar sibling;
+  // We have to stick this in, otherwise strlen() will make it slower than
+  // FlatBuffers:
+  int name_len;
+  char name[kStringLength];
+  double rating;
+  unsigned char postfix;
+};
+
+struct FooBarContainer {
+  FooBar list[kVectorLength];  // 3 copies of the above
+  bool initialized;
+  Enum fruit;
+  int location_len;
+  char location[kStringLength];
+};
+
+struct RawBench : Bench {
+  uint8_t *Encode(void *buf, int64_t &len) {
+    FooBarContainer *fbc = new (buf) FooBarContainer;
+    strcpy(fbc->location, "http://google.com/flatbuffers/");  // Unsafe eek!
+    fbc->location_len = (int)strlen(fbc->location);
+    fbc->fruit = Bananas;
+    fbc->initialized = true;
+    for (int i = 0; i < kVectorLength; i++) {
+      // We add + i to not make these identical copies for a more realistic
+      // compression test.
+      auto &foobar = fbc->list[i];
+      foobar.rating = 3.1415432432445543543 + i;
+      foobar.postfix = '!' + i;
+      strcpy(foobar.name, "Hello, World!");
+      foobar.name_len = (int)strlen(foobar.name);
+      auto &bar = foobar.sibling;
+      bar.ratio = 3.14159f + i;
+      bar.size = 10000 + i;
+      bar.time = 123456 + i;
+      auto &foo = bar.parent;
+      foo.id = 0xABADCAFEABADCAFE + i;
+      foo.count = 10000 + i;
+      foo.length = 1000000 + i;
+      foo.prefix = '@' + i;
+    }
+
+    len = sizeof(FooBarContainer);
+    return reinterpret_cast<uint8_t *>(fbc);
+  };
+
+  int64_t Use(void *decoded) {
+    auto foobarcontainer = reinterpret_cast<FooBarContainer *>(decoded);
+    sum = 0;
+    Add(foobarcontainer->initialized);
+    Add(foobarcontainer->location_len);
+    Add(foobarcontainer->fruit);
+    for (unsigned int i = 0; i < kVectorLength; i++) {
+      auto foobar = &foobarcontainer->list[i];
+      Add(foobar->name_len);
+      Add(foobar->postfix);
+      Add(static_cast<int64_t>(foobar->rating));
+      auto bar = &foobar->sibling;
+      Add(static_cast<int64_t>(bar->ratio));
+      Add(bar->size);
+      Add(bar->time);
+      auto &foo = bar->parent;
+      Add(foo.count);
+      Add(foo.id);
+      Add(foo.length);
+      Add(foo.prefix);
+    }
+    return sum;
+  }
+
+  void *Decode(void *buf, int64_t) { return buf; }
+  void Dealloc(void *) override{};
+};
+
+}  // namespace
+
+std::unique_ptr<Bench> NewRawBench() {
+  return std::unique_ptr<RawBench>(new RawBench());
+}
diff --git a/benchmarks/cpp/raw/raw_bench.h b/benchmarks/cpp/raw/raw_bench.h
new file mode 100644 (file)
index 0000000..68bb278
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef BENCHMARKS_CPP_RAW_RAW_BENCH_H_
+#define BENCHMARKS_CPP_RAW_RAW_BENCH_H_
+
+#include <memory>
+
+#include "benchmarks/cpp/bench.h"
+
+std::unique_ptr<Bench> NewRawBench();
+
+#endif  // BENCHMARKS_CPP_RAW_RAW_BENCH_H_
\ No newline at end of file