[Groonga-commit] groonga/grnxx at be83e7f [master] Add a benchmark for filtering. (#122)

Back to archive index

susumu.yata null+****@clear*****
Mon Dec 1 12:59:43 JST 2014


susumu.yata	2014-12-01 12:59:43 +0900 (Mon, 01 Dec 2014)

  New Revision: be83e7f294e8e8102d07e387a4de2046b6026a91
  https://github.com/groonga/grnxx/commit/be83e7f294e8e8102d07e387a4de2046b6026a91

  Message:
    Add a benchmark for filtering. (#122)

  Added files:
    benchmark/benchmark_filter.cpp
  Modified files:
    .gitignore
    benchmark/Makefile.am

  Modified: .gitignore (+1 -0)
===================================================================
--- .gitignore    2014-11-29 14:51:43 +0900 (126c61d)
+++ .gitignore    2014-12-01 12:59:43 +0900 (27b80e8)
@@ -18,6 +18,7 @@ autom4te.cache/
 benchmark/*.trs
 benchmark/benchmark_adjuster
 benchmark/benchmark_dummy
+benchmark/benchmark_filter
 benchmark/benchmark_sorter
 compile
 config.*

  Modified: benchmark/Makefile.am (+10 -8)
===================================================================
--- benchmark/Makefile.am    2014-11-29 14:51:43 +0900 (bb4d028)
+++ benchmark/Makefile.am    2014-12-01 12:59:43 +0900 (073907c)
@@ -1,16 +1,18 @@
-#TESTS =			\
-#	benchmark_sorter
+noinst_PROGRAMS =		\
+	benchmark_dummy		\
+	benchmark_filter
 
 #	benchmark_adjuster	\
-#	benchmark_dummy
+#	benchmark_sorter
 
-#check_PROGRAMS = $(TESTS)
+benchmark_dummy_SOURCES = benchmark_dummy.cpp
+benchmark_dummy_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la
 
-#benchmark_sorter_SOURCES = benchmark_sorter.cpp
-#benchmark_sorter_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la
+benchmark_filter_SOURCES = benchmark_filter.cpp
+benchmark_filter_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la
 
 #benchmark_adjuster_SOURCES = benchmark_adjuster.cpp
 #benchmark_adjuster_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la
 
-#benchmark_dummy_SOURCES = benchmark_dummy.cpp
-#benchmark_dummy_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la
+#benchmark_sorter_SOURCES = benchmark_sorter.cpp
+#benchmark_sorter_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la

  Added: benchmark/benchmark_filter.cpp (+338 -0) 100644
===================================================================
--- /dev/null
+++ benchmark/benchmark_filter.cpp    2014-12-01 12:59:43 +0900 (9a23c40)
@@ -0,0 +1,338 @@
+/*
+  Copyright (C) 2012-2014  Brazil, Inc.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#include <cassert>
+#include <ctime>
+#include <functional>
+#include <iostream>
+#include <random>
+
+#include "grnxx/array.hpp"
+#include "grnxx/data_types.hpp"
+#include "grnxx/db.hpp"
+#include "grnxx/pipeline.hpp"
+
+namespace {
+
+constexpr size_t SIZE = 10000000;
+constexpr size_t LOOP = 5;
+
+class Timer {
+ public:
+  Timer() : base_(now()) {}
+
+  double elapsed() const {
+    return now() - base_;
+  }
+
+  static double now() {
+    struct timespec ts;
+    ::clock_gettime(CLOCK_MONOTONIC, &ts);
+    return ts.tv_sec + (ts.tv_nsec / 1000000000.0);
+  }
+
+ private:
+  double base_;
+};
+
+grnxx::Array<grnxx::Int> a;
+grnxx::Array<grnxx::Int> b;
+grnxx::Array<grnxx::Int> c;
+
+void generate_data() {
+  std::mt19937_64 rng;
+  a.resize(SIZE);
+  b.resize(SIZE);
+  c.resize(SIZE);
+  for (size_t i = 0; i < SIZE; ++i) {
+    a[i] = grnxx::Int(rng() % 256);
+    b[i] = grnxx::Int(rng() % 256);
+    c[i] = grnxx::Int(rng() % 256);
+  }
+}
+
+void benchmark_grnxx(const grnxx::Table *table,
+                     grnxx::OperatorType logical_operator_type,
+                     grnxx::Int upper_limit) {
+  switch (logical_operator_type) {
+    case grnxx::LOGICAL_AND_OPERATOR: {
+      std::cout << "LOGICAL_AND: ";
+      break;
+    }
+    case grnxx::LOGICAL_OR_OPERATOR: {
+      std::cout << "LOGICAL_OR: ";
+      break;
+    }
+    case grnxx::BITWISE_AND_OPERATOR: {
+      std::cout << "BITWISE_AND: ";
+      break;
+    }
+    case grnxx::BITWISE_OR_OPERATOR: {
+      std::cout << "BITWISE_OR: ";
+      break;
+    }
+    default: {
+      break;
+    }
+  }
+  std::cout << "ratio = " << (100 * upper_limit.raw() / 256) << '%';
+  double min_elapsed = std::numeric_limits<double>::max();
+  for (size_t i = 0; i < LOOP; ++i) {
+    Timer timer;
+
+    auto pipeline_builder = grnxx::PipelineBuilder::create(table);
+    auto cursor = table->create_cursor();
+    pipeline_builder->push_cursor(std::move(cursor));
+    auto expression_builder = grnxx::ExpressionBuilder::create(table);
+    expression_builder->push_column("A");
+    expression_builder->push_constant(upper_limit);
+    expression_builder->push_operator(grnxx::LESS_OPERATOR);
+    expression_builder->push_column("B");
+    expression_builder->push_constant(upper_limit);
+    expression_builder->push_operator(grnxx::LESS_OPERATOR);
+    expression_builder->push_column("C");
+    expression_builder->push_constant(upper_limit);
+    expression_builder->push_operator(grnxx::LESS_OPERATOR);
+    expression_builder->push_operator(logical_operator_type);
+    expression_builder->push_operator(logical_operator_type);
+    auto expression = expression_builder->release();
+    pipeline_builder->push_filter(std::move(expression));
+    auto pipeline = pipeline_builder->release();
+    grnxx::Array<grnxx::Record> records;
+    pipeline->flush(&records);
+
+    double elapsed = timer.elapsed();
+    if (elapsed < min_elapsed) {
+      min_elapsed = elapsed;
+    }
+  }
+  std::cout << ", min. elapsed [s] = " << min_elapsed << std::endl;
+}
+
+void benchmark_grnxx(const grnxx::Table *table,
+                     grnxx::OperatorType logical_operator_type) {
+  benchmark_grnxx(table, logical_operator_type, grnxx::Int(16));
+  benchmark_grnxx(table, logical_operator_type, grnxx::Int(32));
+  benchmark_grnxx(table, logical_operator_type, grnxx::Int(64));
+  benchmark_grnxx(table, logical_operator_type, grnxx::Int(128));
+  benchmark_grnxx(table, logical_operator_type, grnxx::Int(192));
+  benchmark_grnxx(table, logical_operator_type, grnxx::Int(224));
+  benchmark_grnxx(table, logical_operator_type, grnxx::Int(240));
+}
+
+void benchmark_grnxx() {
+  std::cout << __PRETTY_FUNCTION__ << std::endl;
+
+  auto db = grnxx::open_db("");
+  auto table = db->create_table("Table");
+  auto col_a = table->create_column("A", grnxx::INT_DATA);
+  auto col_b = table->create_column("B", grnxx::INT_DATA);
+  auto col_c = table->create_column("C", grnxx::INT_DATA);
+  for (size_t i = 0; i < SIZE; ++i) {
+    grnxx::Int row_id = table->insert_row();
+    col_a->set(row_id, a[i]);
+    col_b->set(row_id, b[i]);
+    col_c->set(row_id, c[i]);
+  }
+
+  benchmark_grnxx(table, grnxx::LOGICAL_AND_OPERATOR);
+  benchmark_grnxx(table, grnxx::LOGICAL_OR_OPERATOR);
+  benchmark_grnxx(table, grnxx::BITWISE_AND_OPERATOR);
+  benchmark_grnxx(table, grnxx::BITWISE_OR_OPERATOR);
+}
+
+void benchmark_native_batch_and(grnxx::Int upper_limit) {
+  std::cout << "LOGICAL_AND: ";
+  std::cout << "ratio = " << (100 * upper_limit.raw() / 256) << '%';
+  double min_elapsed = std::numeric_limits<double>::max();
+  for (size_t i = 0; i < LOOP; ++i) {
+    Timer timer;
+
+    grnxx::Array<grnxx::Record> records;
+    records.resize(SIZE);
+    for (size_t j = 0; j < SIZE; ++j) {
+      records[j].row_id = grnxx::Int(j);
+      records[j].score = grnxx::Float(0.0);
+    }
+    size_t count = 0;
+    for (size_t j = 0; j < SIZE; ++j) {
+      if ((a[records[j].row_id.raw()] < upper_limit).is_true() &&
+          (b[records[j].row_id.raw()] < upper_limit).is_true() &&
+          (c[records[j].row_id.raw()] < upper_limit).is_true()) {
+        records[count] = grnxx::Record(grnxx::Int(j), grnxx::Float(0.0));
+        ++count;
+      }
+    }
+    records.resize(count);
+
+    double elapsed = timer.elapsed();
+    if (elapsed < min_elapsed) {
+      min_elapsed = elapsed;
+    }
+  }
+  std::cout << ", min. elapsed [s] = " << min_elapsed << std::endl;
+}
+
+void benchmark_native_batch_and() {
+  benchmark_native_batch_and(grnxx::Int(16));
+  benchmark_native_batch_and(grnxx::Int(32));
+  benchmark_native_batch_and(grnxx::Int(64));
+  benchmark_native_batch_and(grnxx::Int(128));
+  benchmark_native_batch_and(grnxx::Int(192));
+  benchmark_native_batch_and(grnxx::Int(224));
+  benchmark_native_batch_and(grnxx::Int(240));
+}
+
+void benchmark_native_batch_or(grnxx::Int upper_limit) {
+  std::cout << "LOGICAL_OR: ";
+  std::cout << "ratio = " << (100 * upper_limit.raw() / 256) << '%';
+  double min_elapsed = std::numeric_limits<double>::max();
+  for (size_t i = 0; i < LOOP; ++i) {
+    Timer timer;
+
+    grnxx::Array<grnxx::Record> records;
+    records.resize(SIZE);
+    for (size_t j = 0; j < SIZE; ++j) {
+      records[j].row_id = grnxx::Int(j);
+      records[j].score = grnxx::Float(0.0);
+    }
+    size_t count = 0;
+    for (size_t j = 0; j < SIZE; ++j) {
+      if ((a[records[j].row_id.raw()] < upper_limit).is_true() ||
+          (b[records[j].row_id.raw()] < upper_limit).is_true() ||
+          (c[records[j].row_id.raw()] < upper_limit).is_true()) {
+        records[count] = grnxx::Record(grnxx::Int(j), grnxx::Float(0.0));
+        ++count;
+      }
+    }
+    records.resize(count);
+
+    double elapsed = timer.elapsed();
+    if (elapsed < min_elapsed) {
+      min_elapsed = elapsed;
+    }
+  }
+  std::cout << ", min. elapsed [s] = " << min_elapsed << std::endl;
+}
+
+void benchmark_native_batch_or() {
+  benchmark_native_batch_or(grnxx::Int(16));
+  benchmark_native_batch_or(grnxx::Int(32));
+  benchmark_native_batch_or(grnxx::Int(64));
+  benchmark_native_batch_or(grnxx::Int(128));
+  benchmark_native_batch_or(grnxx::Int(192));
+  benchmark_native_batch_or(grnxx::Int(224));
+  benchmark_native_batch_or(grnxx::Int(240));
+}
+
+void benchmark_native_batch() {
+  std::cout << __PRETTY_FUNCTION__ << std::endl;
+
+  benchmark_native_batch_and();
+  benchmark_native_batch_or();
+}
+
+void benchmark_native_sequential_and(grnxx::Int upper_limit) {
+  std::cout << "LOGICAL_AND: ";
+  std::cout << "ratio = " << (100 * upper_limit.raw() / 256) << '%';
+  double min_elapsed = std::numeric_limits<double>::max();
+  for (size_t i = 0; i < LOOP; ++i) {
+    Timer timer;
+
+    grnxx::Array<grnxx::Record> records;
+    for (size_t j = 0; j < SIZE; ++j) {
+      if ((a[j] < upper_limit).is_true() &&
+          (b[j] < upper_limit).is_true() &&
+          (c[j] < upper_limit).is_true()) {
+        records.push_back(grnxx::Record(grnxx::Int(j), grnxx::Float(0.0)));
+      }
+    }
+
+    double elapsed = timer.elapsed();
+    if (elapsed < min_elapsed) {
+      min_elapsed = elapsed;
+    }
+  }
+  std::cout << ", min. elapsed [s] = " << min_elapsed << std::endl;
+}
+
+void benchmark_native_sequential_and() {
+  benchmark_native_sequential_and(grnxx::Int(16));
+  benchmark_native_sequential_and(grnxx::Int(32));
+  benchmark_native_sequential_and(grnxx::Int(64));
+  benchmark_native_sequential_and(grnxx::Int(128));
+  benchmark_native_sequential_and(grnxx::Int(192));
+  benchmark_native_sequential_and(grnxx::Int(224));
+  benchmark_native_sequential_and(grnxx::Int(240));
+}
+
+void benchmark_native_sequential_or(grnxx::Int upper_limit) {
+  std::cout << "LOGICAL_OR: ";
+  std::cout << "ratio = " << (100 * upper_limit.raw() / 256) << '%';
+  double min_elapsed = std::numeric_limits<double>::max();
+  for (size_t i = 0; i < LOOP; ++i) {
+    Timer timer;
+
+    grnxx::Array<grnxx::Record> records;
+    for (size_t j = 0; j < SIZE; ++j) {
+      if ((a[j] < upper_limit).is_true() ||
+          (b[j] < upper_limit).is_true() ||
+          (c[j] < upper_limit).is_true()) {
+        records.push_back(grnxx::Record(grnxx::Int(j), grnxx::Float(0.0)));
+      }
+    }
+
+    double elapsed = timer.elapsed();
+    if (elapsed < min_elapsed) {
+      min_elapsed = elapsed;
+    }
+  }
+  std::cout << ", min. elapsed [s] = " << min_elapsed << std::endl;
+}
+
+void benchmark_native_sequential_or() {
+  benchmark_native_sequential_or(grnxx::Int(16));
+  benchmark_native_sequential_or(grnxx::Int(32));
+  benchmark_native_sequential_or(grnxx::Int(64));
+  benchmark_native_sequential_or(grnxx::Int(128));
+  benchmark_native_sequential_or(grnxx::Int(192));
+  benchmark_native_sequential_or(grnxx::Int(224));
+  benchmark_native_sequential_or(grnxx::Int(240));
+}
+
+void benchmark_native_sequential() {
+  std::cout << __PRETTY_FUNCTION__ << std::endl;
+
+  benchmark_native_sequential_and();
+  benchmark_native_sequential_or();
+}
+
+void benchmark_native() {
+  benchmark_native_batch();
+  benchmark_native_sequential();
+}
+
+}  // namespace
+
+int main() {
+  generate_data();
+
+  benchmark_grnxx();
+  benchmark_native();
+
+  return 0;
+}
-------------- next part --------------
HTML����������������������������...
다운로드 



More information about the Groonga-commit mailing list
Back to archive index