susumu.yata
null+****@clear*****
Wed Nov 26 19:31:34 JST 2014
susumu.yata 2014-11-26 19:31:34 +0900 (Wed, 26 Nov 2014) New Revision: 214c603085bb35ed959936691b220be326ffa947 https://github.com/groonga/grnxx/commit/214c603085bb35ed959936691b220be326ffa947 Message: Add a benchmark for Sorter. (#117) Added files: benchmark/benchmark_sorter.cpp Modified files: .gitignore benchmark/Makefile.am Modified: .gitignore (+1 -0) =================================================================== --- .gitignore 2014-11-26 18:41:47 +0900 (3208cbb) +++ .gitignore 2014-11-26 19:31:34 +0900 (126c61d) @@ -18,6 +18,7 @@ autom4te.cache/ benchmark/*.trs benchmark/benchmark_adjuster benchmark/benchmark_dummy +benchmark/benchmark_sorter compile config.* configure Modified: benchmark/Makefile.am (+6 -1) =================================================================== --- benchmark/Makefile.am 2014-11-26 18:41:47 +0900 (2f8bb17) +++ benchmark/Makefile.am 2014-11-26 19:31:34 +0900 (bb4d028) @@ -1,9 +1,14 @@ -#TESTS = \ +#TESTS = \ +# benchmark_sorter + # benchmark_adjuster \ # benchmark_dummy #check_PROGRAMS = $(TESTS) +#benchmark_sorter_SOURCES = benchmark_sorter.cpp +#benchmark_sorter_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la + #benchmark_adjuster_SOURCES = benchmark_adjuster.cpp #benchmark_adjuster_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la Added: benchmark/benchmark_sorter.cpp (+443 -0) 100644 =================================================================== --- /dev/null +++ benchmark/benchmark_sorter.cpp 2014-11-26 19:31:34 +0900 (ad0cd95) @@ -0,0 +1,443 @@ +/* + 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 <time.h> + +#include <cassert> +#include <iostream> +#include <random> + +#include "grnxx/column.hpp" +#include "grnxx/cursor.hpp" +#include "grnxx/db.hpp" +#include "grnxx/expression.hpp" +#include "grnxx/table.hpp" +#include "grnxx/sorter.hpp" + +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::Record> create_records(grnxx::Table *table) { + auto cursor = table->create_cursor(); + grnxx::Array<grnxx::Record> records; + size_t count = cursor->read_all(&records); + assert(count == table->num_rows()); + return records; +} + +void benchmark_int() { + constexpr size_t NUM_ROWS = 1 << 21; + auto db = grnxx::open_db(""); + auto table = db->create_table("Table"); + auto float_1 = table->create_column("Float_1", grnxx::FLOAT_DATA); + auto float_2 = table->create_column("Float_2", grnxx::FLOAT_DATA); + auto float_3 = table->create_column("Float_3", grnxx::FLOAT_DATA); + std::mt19937_64 rng; + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + if ((rng() % 4) != 0) { + float_1->set(row_id, grnxx::Float(1.0 * (rng() % 256) / 255)); + } + if ((rng() % 4) != 0) { + float_2->set(row_id, grnxx::Float(1.0 * (rng() % 65536) / 65535)); + } + if ((rng() % 4) != 0) { + float_3->set(row_id, grnxx::Float(1.0 * rng() / rng.max())); + } + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(1); + expression_builder->push_column("Float_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Float_1" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(1); + expression_builder->push_column("Float_2"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Float_2" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(1); + expression_builder->push_column("Float_3"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Float_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(2); + expression_builder->push_column("Float_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Float_2"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Float_1, Float_2" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(2); + expression_builder->push_column("Float_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Float_3"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Float_1, Float_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(2); + expression_builder->push_column("Float_2"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Float_3"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Float_2, Float_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(3); + expression_builder->push_column("Float_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Float_2"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Float_3"); + orders[2].expression = std::move(expression_builder->release()); + orders[2].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Float_1, Float_2, Float_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } +} + +void benchmark_float() { + constexpr size_t NUM_ROWS = 1 << 21; + auto db = grnxx::open_db(""); + auto table = db->create_table("Table"); + auto int_1 = table->create_column("Int_1", grnxx::INT_DATA); + auto int_2 = table->create_column("Int_2", grnxx::INT_DATA); + auto int_3 = table->create_column("Int_3", grnxx::INT_DATA); + std::mt19937_64 rng; + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + if ((rng() % 4) != 0) { + int_1->set(row_id, grnxx::Int(rng() % 256)); + } + if ((rng() % 4) != 0) { + int_2->set(row_id, grnxx::Int(rng() % 65536)); + } + if ((rng() % 4) != 0) { + int_3->set(row_id, grnxx::Int(rng())); + } + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(1); + expression_builder->push_column("Int_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Int_1" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(1); + expression_builder->push_column("Int_2"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Int_2" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(1); + expression_builder->push_column("Int_3"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Int_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(2); + expression_builder->push_column("Int_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Int_2"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Int_1, Int_2" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(2); + expression_builder->push_column("Int_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Int_3"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Int_1, Int_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(2); + expression_builder->push_column("Int_2"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Int_3"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Int_2, Int_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } + + { + double best_elapsed = std::numeric_limits<double>::max(); + for (int i = 0; i < 5; ++i) { + grnxx::Array<grnxx::Record> records = create_records(table); + Timer timer; + auto expression_builder = grnxx::ExpressionBuilder::create(table); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(3); + expression_builder->push_column("Int_1"); + orders[0].expression = std::move(expression_builder->release()); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Int_2"); + orders[1].expression = std::move(expression_builder->release()); + orders[1].type = grnxx::SORTER_REGULAR_ORDER; + expression_builder->push_column("Int_3"); + orders[2].expression = std::move(expression_builder->release()); + orders[2].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); + sorter->sort(&records); + double elapsed = timer.elapsed(); + if (elapsed < best_elapsed) { + best_elapsed = elapsed; + } + } + std::cout << "Int_1, Int_2, Int_3" << std::endl; + std::cout << "best elapsed [s] = " << best_elapsed << std::endl; + } +} + +int main() { + benchmark_int(); + benchmark_float(); + return 0; +} -------------- next part -------------- HTML����������������������������...ダウンロード