diff options
Diffstat (limited to '')
27 files changed, 3718 insertions, 0 deletions
diff --git a/storage/mroonga/vendor/groonga/benchmark/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/Makefile.am new file mode 100644 index 00000000..a2a8b29a --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/Makefile.am @@ -0,0 +1,153 @@ +SUBDIRS = \ + fixtures \ + lib + +NONEXISTENT_CXX_SOURCE = nonexistent.cpp + +if WITH_BENCHMARK +noinst_PROGRAMS = \ + bench-table-factory \ + bench-geo-distance \ + bench-geo-select \ + bench-ctx-create \ + bench-query-optimizer \ + bench-range-select \ + bench-result-set \ + bench-between-sequential \ + bench-nfkc \ + bench-cache +endif + +EXTRA_DIST = \ + bench-geo-select.sh \ + bench-query-optimizer-ddl.grn \ + geo-select-generate-grn.rb + +AM_CPPFLAGS = \ + -I$(srcdir) \ + -I$(srcdir)/lib \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib \ + $(GROONGA_INCLUDEDIR) + +AM_CFLAGS = \ + $(GLIB_CFLAGS) + +LIBS = \ + $(top_builddir)/lib/libgroonga.la \ + $(top_builddir)/benchmark/lib/libbenchmark.la \ + $(GLIB_LIBS) + +bench_table_factory_SOURCES = bench-table-factory.c +nodist_EXTRA_bench_table_factory_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_geo_distance_SOURCES = bench-geo-distance.c +nodist_EXTRA_bench_geo_distance_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_geo_select_SOURCES = bench-geo-select.c +nodist_EXTRA_bench_geo_select_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_ctx_create_SOURCES = bench-ctx-create.c +nodist_EXTRA_bench_ctx_create_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_query_optimizer_SOURCES = bench-query-optimizer.c +nodist_EXTRA_bench_query_optimizer_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_range_select_SOURCES = bench-range-select.c +nodist_EXTRA_bench_range_select_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_result_set_SOURCES = bench-result-set.c +nodist_EXTRA_bench_result_set_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_between_sequential_SOURCES = bench-between-sequential.c +nodist_EXTRA_bench_between_sequential_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_nfkc_SOURCES = bench-nfkc.c +nodist_EXTRA_bench_nfkc_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +bench_cache_SOURCES = bench-cache.c +nodist_EXTRA_bench_cache_SOURCES = $(NONEXISTENT_CXX_SOURCE) + +benchmarks = \ + run-bench-table-factory \ + run-bench-geo-distance \ + run-bench-geo-select \ + run-bench-ctx-create \ + run-bench-query-optimizer \ + run-bench-range-select \ + run-bench-result-set \ + run-bench-between-sequential \ + run-bench-nfkc \ + run-bench-cache + +run-bench-table-factory: bench-table-factory + @echo $@: + env \ + GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \ + ./bench-table-factory + +run-bench-geo-distance: bench-geo-distance + @echo $@: + env \ + GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \ + ./bench-geo-distance + +run-bench-geo-select: bench-geo-select + @echo $@: + env \ + RUBY="$(RUBY)" \ + GROONGA="$(GROONGA)" \ + GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \ + srcdir="$(srcdir)" \ + $(srcdir)/bench-geo-select.sh + +run-bench-ctx-create: bench-ctx-create + @echo $@: + env \ + GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \ + ./bench-ctx-create + +run-bench-query-optimizer: bench-query-optimizer + @echo $@: + @rm -rf tmp/query-optimizer + @mkdir -p tmp/query-optimizer + @env \ + GRN_RUBY_SCRIPTS_DIR=$(top_srcdir)/lib/mrb/scripts \ + ../src/groonga \ + --file $(srcdir)/bench-query-optimizer-ddl.grn \ + -n tmp/query-optimizer/db > /dev/null + env \ + GRN_RUBY_SCRIPTS_DIR=$(top_srcdir)/lib/mrb/scripts \ + ./bench-query-optimizer + +run-bench-range-select: bench-range-select + @echo $@: + @[ ! -e tmp ] && ln -s /dev/shm tmp || : + @mkdir -p tmp/range-select + env \ + GRN_RUBY_SCRIPTS_DIR=$(top_srcdir)/lib/mrb/scripts \ + ./bench-range-select + +run-bench-result-set: bench-result-set + @echo $@: + env \ + GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \ + ./bench-result-set + +run-bench-between-sequential: bench-between-sequential + @echo $@: + @[ ! -e tmp ] && ln -s /dev/shm tmp || : + @mkdir -p tmp/between-sequential + env \ + GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \ + ./bench-between-sequential + +run-bench-nfkc: bench-nfkc + @echo $@: + ./bench-nfkc + +run-bench-cache: bench-cache + @echo $@: + ./bench-cache + +benchmark: $(benchmarks) diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c b/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c new file mode 100644 index 00000000..f0b7cf05 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c @@ -0,0 +1,276 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz + + CFLAGS: -O2 -g + + Groonga: e2971d9a555a90724b76964cc8c8805373500b4a + % make --quiet -C benchmark run-bench-between-sequential + run-bench-between-sequential: + Process 10 times in each pattern + (total) (average) (median) + ( 500, 600] ( 1000): between: (0.0528s) (0.0053s) (0.0043s) + ( 500, 600] ( 1000): range: (0.0120s) (0.0012s) (0.2500ms) + ( 5000, 5100] ( 10000): between: (0.4052s) (0.0405s) (0.0395s) + ( 5000, 5100] ( 10000): range: (0.0197s) (0.0020s) (0.0010s) + ( 50000, 50100] ( 100000): between: (3.9343s) (0.3934s) (0.3900s) + ( 50000, 50100] ( 100000): range: (0.0969s) (0.0097s) (0.0088s) + (500000, 500100] (1000000): between: (38.2969s) (3.8297s) (3.7983s) + (500000, 500100] (1000000): range: (0.9158s) (0.0916s) (0.0900s) + + Groonga: 35e4e431bb7660b3170e98c329f7219bd6723f05 + % make --quiet -C benchmark run-bench-between-sequential + run-bench-between-sequential: + Process 10 times in each pattern + (total) (average) (median) + ( 500, 600] ( 1000): between: (0.0130s) (0.0013s) (0.2590ms) + ( 500, 600] ( 1000): range: (0.0124s) (0.0012s) (0.2530ms) + ( 5000, 5100] ( 10000): between: (0.0163s) (0.0016s) (0.6440ms) + ( 5000, 5100] ( 10000): range: (0.0205s) (0.0021s) (0.0011s) + ( 50000, 50100] ( 100000): between: (0.0611s) (0.0061s) (0.0051s) + ( 50000, 50100] ( 100000): range: (0.1004s) (0.0100s) (0.0091s) + (500000, 500100] (1000000): between: (0.4518s) (0.0452s) (0.0442s) + (500000, 500100] (1000000): range: (0.8866s) (0.0887s) (0.0878s) +*/ + +#include <stdio.h> +#include <string.h> + +#include <grn_db.h> +#include <groonga.h> + +#include "lib/benchmark.h" + +#define GET(context, name) (grn_ctx_get(context, name, strlen(name))) + +typedef struct _BenchmarkData +{ + grn_ctx context; + grn_obj *database; + guint n_records; + const gchar *command; +} BenchmarkData; + +static void +run_command(grn_ctx *context, const gchar *command) +{ + gchar *response; + unsigned int response_length; + int flags; + + grn_ctx_send(context, command, strlen(command), 0); + grn_ctx_recv(context, &response, &response_length, &flags); +} + +static void +bench(gpointer user_data) +{ + BenchmarkData *data = user_data; + grn_ctx *context = &(data->context); + + run_command(context, data->command); +} + +static gchar * +get_tmp_dir(void) +{ + gchar *current_dir; + gchar *tmp_dir; + + current_dir = g_get_current_dir(); + tmp_dir = g_build_filename(current_dir, "tmp", NULL); + g_free(current_dir); + + return tmp_dir; +} + +static void +setup_database(BenchmarkData *data) +{ + grn_ctx *context = &(data->context); + gchar *tmp_dir; + gchar *database_last_component_name; + gchar *database_path; + guint i; + + tmp_dir = get_tmp_dir(); + database_last_component_name = g_strdup_printf("db-%d", data->n_records); + database_path = g_build_filename(tmp_dir, + "between-sequential", + database_last_component_name, + NULL); + g_free(database_last_component_name); + + if (g_file_test(database_path, G_FILE_TEST_EXISTS)) { + data->database = grn_db_open(context, database_path); + run_command(context, "dump"); + } else { + data->database = grn_db_create(context, database_path, NULL); + + run_command(context, "table_create Entries TABLE_NO_KEY"); + run_command(context, "column_create Entries rank COLUMN_SCALAR Int32"); + + run_command(context, "load --table Entries"); + run_command(context, "["); + for (i = 0; i < data->n_records; i++) { +#define BUFFER_SIZE 4096 + gchar buffer[BUFFER_SIZE]; + const gchar *separator; + if (i == (data->n_records - 1)) { + separator = ""; + } else { + separator = ","; + } + snprintf(buffer, BUFFER_SIZE, "{\"rank\": %u}%s", i, separator); + run_command(context, buffer); +#undef BUFFER_SIZE + } + run_command(context, "]"); + } + + g_free(database_path); +} + +static void +bench_startup(BenchmarkData *data) +{ + grn_ctx_init(&(data->context), 0); + setup_database(data); +} + +static void +bench_shutdown(BenchmarkData *data) +{ + grn_ctx *context = &(data->context); + + grn_obj_close(context, data->database); + grn_ctx_fin(context); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchReporter *reporter; + gint n = 10; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + + g_print("Process %d times in each pattern\n", n); + + bench_init(&argc, &argv); + reporter = bench_reporter_new(); + + { + BenchmarkData data_small_between; + BenchmarkData data_small_range; + BenchmarkData data_medium_between; + BenchmarkData data_medium_range; + BenchmarkData data_large_between; + BenchmarkData data_large_range; + BenchmarkData data_very_large_between; + BenchmarkData data_very_large_range; + +#define REGISTER(data, n_records_, min, max, is_between) \ + do { \ + gchar *label; \ + label = \ + g_strdup_printf("(%6d, %6d] (%7d): %7s", \ + min, max, n_records_, \ + is_between ? "between" : "range"); \ + data.n_records = n_records_; \ + if (is_between) { \ + data.command = \ + "select Entries --cache no " \ + "--filter " \ + "'between(rank, " #min ", \"exclude\"," \ + " " #max ", \"include\")'"; \ + } else { \ + data.command = \ + "select Entries --cache no " \ + "--filter 'rank > " #min " && rank <= " #max "'"; \ + } \ + bench_startup(&data); \ + bench_reporter_register(reporter, label, \ + n, \ + NULL, \ + bench, \ + NULL, \ + &data); \ + g_free(label); \ + } while(FALSE) + + REGISTER(data_small_between, + 1000, + 500, 600, + TRUE); + REGISTER(data_small_range, + 1000, + 500, 600, + FALSE); + REGISTER(data_medium_between, + 10000, + 5000, 5100, + TRUE); + REGISTER(data_medium_range, + 10000, + 5000, 5100, + FALSE); + REGISTER(data_large_between, + 100000, + 50000, 50100, + TRUE); + REGISTER(data_large_range, + 100000, + 50000, 50100, + FALSE); + REGISTER(data_very_large_between, + 1000000, + 500000, 500100, + TRUE); + REGISTER(data_very_large_range, + 1000000, + 500000, 500100, + FALSE); + +#undef REGISTER + + bench_reporter_run(reporter); + + bench_shutdown(&data_small_between); + bench_shutdown(&data_small_range); + bench_shutdown(&data_medium_between); + bench_shutdown(&data_medium_range); + bench_shutdown(&data_large_between); + bench_shutdown(&data_large_range); + bench_shutdown(&data_very_large_between); + bench_shutdown(&data_very_large_range); + } + g_object_unref(reporter); + + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-cache.c b/storage/mroonga/vendor/groonga/benchmark/bench-cache.c new file mode 100644 index 00000000..104a7c19 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-cache.c @@ -0,0 +1,155 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + Groonga: eb65125330b3a8f920693ef3ad53011c7412f2c9 + CFLAGS: -O2 -g3 + CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz + + % make --silent -C benchmark run-bench-cache + run-bench-cache: + (total) (average) (median) + 1000: (0.0458s) (0.4576ms) (0.4170ms) + 10000: (0.3464s) (0.0035s) (0.0034s) + % GRN_CACHE_TYPE=persistent make --silent -C benchmark run-bench-cache + run-bench-cache: + (total) (average) (median) + 1000: (0.0480s) (0.4801ms) (0.4700ms) + 10000: (0.4033s) (0.0040s) (0.0040s) + */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#include <grn_cache.h> + +#include "lib/benchmark.h" + +typedef struct _BenchmarkData +{ + grn_ctx *context; + grn_cache *cache; + grn_obj value; +} BenchmarkData; + +static void +bench_n(BenchmarkData *data, gint64 n) +{ + gint64 i; + grn_ctx *ctx; + grn_cache *cache; + grn_obj *value; + grn_obj fetch_buffer; + + ctx = data->context; + cache = data->cache; + value = &(data->value); + GRN_TEXT_INIT(&fetch_buffer, 0); + for (i = 0; i < n; i++) { + char key[GRN_TABLE_MAX_KEY_SIZE]; + grn_snprintf(key, + GRN_TABLE_MAX_KEY_SIZE, + GRN_TABLE_MAX_KEY_SIZE, + "key:%" GRN_FMT_INT64D, + i); + GRN_BULK_REWIND(&fetch_buffer); + grn_cache_fetch(ctx, cache, key, strlen(key), &fetch_buffer); + grn_cache_update(ctx, cache, key, strlen(key), value); + } + GRN_OBJ_FIN(ctx, &fetch_buffer); +} + +static void +bench_1000(gpointer user_data) +{ + BenchmarkData *data = user_data; + bench_n(data, 1000); +} + +static void +bench_10000(gpointer user_data) +{ + BenchmarkData *data = user_data; + bench_n(data, 10000); +} + +static void +bench_setup(gpointer user_data) +{ + BenchmarkData *data = user_data; + + data->cache = grn_cache_open(data->context); + GRN_TEXT_INIT(&(data->value), 0); + while (GRN_TEXT_LEN(&(data->value)) < 1024) { + GRN_TEXT_PUTS(data->context, &(data->value), "XXXXXXXXXXX"); + } +} + +static void +bench_teardown(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_obj_close(data->context, &(data->value)); + grn_cache_close(data->context, data->cache); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchmarkData data; + BenchReporter *reporter; + gchar *base_dir; + grn_ctx ctx; + gint n = 100; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + grn_ctx_init(&ctx, 0); + + data.context = &ctx; + + base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL); + bench_utils_remove_path_recursive_force(base_dir); + g_mkdir_with_parents(base_dir, 0755); + + reporter = bench_reporter_new(); + bench_reporter_register(reporter, "1000", n, + bench_setup, bench_1000, bench_teardown, &data); + bench_reporter_register(reporter, "10000", n, + bench_setup, bench_10000, bench_teardown, &data); + bench_reporter_run(reporter); + g_object_unref(reporter); + + grn_ctx_fin(&ctx); + + bench_utils_remove_path_recursive_force(base_dir); + + bench_quit(); + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c b/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c new file mode 100644 index 00000000..576ac8ee --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c @@ -0,0 +1,198 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + Groonga: 6b128f318d682e50648f3b82c5f7956f3bcb3fe8 + CFLAGS: -O0 -g3 + % (cd benchmark/ && make --quiet run-bench-ctx-create) + run-bench-ctx-create: + (time) + with mruby1: 288KB (0.0091s) + without mruby1: 28KB (0.0240ms) + with mruby2: 0KB (0.0097s) + without mruby2: 0KB (0.0220ms) + + Groonga: c4379140c02699e3c74b94cd9e7b88d372202aa5 + CFLAGS: -O2 -g + % make --quiet -C benchmark run-bench-ctx-create + run-bench-ctx-create: + (time) + with mruby1: 524KB (0.0041s) + without mruby1: 32KB (0.0220ms) + with mruby2: 0KB (0.0040s) + without mruby2: 0KB (0.0200ms) +*/ + +#include <stdlib.h> + +#include <glib.h> + +#include <groonga.h> + +#include "lib/benchmark.h" + +typedef struct _BenchmarkData { + grn_ctx context; + grn_obj *database; + guint memory_usage_before; +} BenchmarkData; + +static guint +get_memory_usage(void) +{ + GRegex *vm_rss_pattern; + gchar *status; + GMatchInfo *match_info; + gchar *vm_rss_string; + guint vm_rss; + + g_file_get_contents("/proc/self/status", &status, NULL, NULL); + + vm_rss_pattern = g_regex_new("VmRSS:\\s*(\\d*)\\s+kB", 0, 0, NULL); + if (!g_regex_match(vm_rss_pattern, status, 0, &match_info)) { + g_print("not match...: %s\n", status); + return 0; + } + vm_rss_string = g_match_info_fetch(match_info, 1); + vm_rss = atoi(vm_rss_string); + g_free(vm_rss_string); + g_match_info_free(match_info); + g_regex_unref(vm_rss_pattern); + g_free(status); + + return vm_rss; +} + +static void +bench_with_mruby(gpointer user_data) +{ + BenchmarkData *data = user_data; + + g_setenv("GRN_MRUBY_ENABLED", "yes", TRUE); + grn_ctx_init(&(data->context), 0); + grn_ctx_use(&(data->context), data->database); +} + +static void +bench_without_mruby(gpointer user_data) +{ + BenchmarkData *data = user_data; + + g_setenv("GRN_MRUBY_ENABLED", "no", TRUE); + grn_ctx_init(&(data->context), 0); + grn_ctx_use(&(data->context), data->database); +} + +static void +bench_setup(gpointer user_data) +{ + BenchmarkData *data = user_data; + + data->memory_usage_before = get_memory_usage(); +} + +static void +bench_teardown(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_ctx_fin(&(data->context)); + g_print("%3dKB ", get_memory_usage() - data->memory_usage_before); +} + +static gchar * +get_tmp_dir(void) +{ + gchar *current_dir; + gchar *tmp_dir; + + current_dir = g_get_current_dir(); + tmp_dir = g_build_filename(current_dir, "tmp", NULL); + g_free(current_dir); + + return tmp_dir; +} + +static grn_obj * +setup_database(grn_ctx *context) +{ + gchar *tmp_dir; + gchar *database_path; + grn_obj *database; + + tmp_dir = get_tmp_dir(); + database_path = g_build_filename(tmp_dir, "ctx-create", "db", NULL); + database = grn_db_open(context, database_path); + + g_free(database_path); + + return database; +} + +static void +teardown_database(grn_ctx *context, grn_obj *database) +{ + grn_obj_close(context, database); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + grn_ctx context; + BenchmarkData data; + BenchReporter *reporter; + gint n = 1; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + grn_ctx_init(&context, 0); + + data.database = setup_database(&context); + + reporter = bench_reporter_new(); + +#define REGISTER(label, bench_function) \ + bench_reporter_register(reporter, label, n, \ + bench_setup, \ + bench_function, \ + bench_teardown, \ + &data) + REGISTER("with mruby1", bench_with_mruby); + REGISTER("without mruby1", bench_without_mruby); + REGISTER("with mruby2", bench_with_mruby); + REGISTER("without mruby2", bench_without_mruby); +#undef REGISTER + + bench_reporter_run(reporter); + g_object_unref(reporter); + + teardown_database(&context, data.database); + + grn_ctx_fin(&context); + + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c new file mode 100644 index 00000000..0b648a1c --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c @@ -0,0 +1,506 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2009-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + groonga: 3ad91b868909444f66a36dbcbdbe2292ed14bd72 + CFLAGS: -O0 -g + CPU: AMD Athlon(tm) 64 Processor 3000+ + + % test/benchmark/bench-geo-distance + (time) + rectangular (WGS84): (0.0813662) + rectangular (TOKYO): (0.0621928) + spherical (WGS84): (0.0760155) + spherical (TOKYO): (0.0660843) + hubeny (WGS84): (0.110684) + hubeny (TOKYO): (0.0702277) + % test/benchmark/bench-geo-distance + (time) + rectangular (WGS84): (0.0742154) + rectangular (TOKYO): (0.0816863) + spherical (WGS84): (0.074316) + spherical (TOKYO): (0.0696254) + hubeny (WGS84): (0.0650147) + hubeny (TOKYO): (0.0644057) + % test/benchmark/bench-geo-distance + (time) + rectangular (WGS84): (0.0781161) + rectangular (TOKYO): (0.0706679) + spherical (WGS84): (0.075739) + spherical (TOKYO): (0.0809402) + hubeny (WGS84): (0.0727023) + hubeny (TOKYO): (0.0718146) + */ + +#include <string.h> +#include <stdlib.h> + +#include <grn_db.h> +#include <groonga.h> + +#include "lib/benchmark.h" + +#define GET(context, name) (grn_ctx_get(context, name, strlen(name))) + +grn_obj *grn_expr_get_value(grn_ctx *ctx, grn_obj *expr, int offset); + +typedef struct _BenchmarkData +{ + gchar *base_dir; + gboolean report_result; + + grn_ctx *context; + grn_obj *database; + grn_obj *geo_distance_proc; + grn_obj *expression; + grn_obj *start_point; + grn_obj *end_point; +} BenchmarkData; + +static void +bench_geo_distance(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_proc_call(data->context, data->geo_distance_proc, + 2, data->expression); +} + +static void +bench_setup_common(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_ctx_init(data->context, GRN_CTX_USE_QL); + data->database = grn_db_create(data->context, NULL, NULL); + data->expression = grn_expr_create(data->context, NULL, 0); +} + +static void +bench_setup_points(gpointer user_data, + const gchar *start_point_string, + const gchar *end_point_string, + grn_builtin_type wgs84_or_tgs) +{ + BenchmarkData *data = user_data; + grn_obj start_point_text, end_point_text; + + GRN_TEXT_INIT(&start_point_text, 0); + GRN_TEXT_INIT(&end_point_text, 0); + GRN_TEXT_SETS(data->context, &start_point_text, start_point_string); + GRN_TEXT_SETS(data->context, &end_point_text, end_point_string); + + data->start_point = grn_obj_open(data->context, GRN_BULK, 0, wgs84_or_tgs); + data->end_point = grn_obj_open(data->context, GRN_BULK, 0, wgs84_or_tgs); + grn_obj_cast(data->context, &start_point_text, data->start_point, GRN_FALSE); + grn_obj_cast(data->context, &end_point_text, data->end_point, GRN_FALSE); + grn_ctx_push(data->context, data->start_point); + grn_ctx_push(data->context, data->end_point); + + grn_obj_unlink(data->context, &start_point_text); + grn_obj_unlink(data->context, &end_point_text); +} + +static void +bench_setup_wgs84(gpointer user_data) +{ + bench_setup_common(user_data); + bench_setup_points(user_data, + "127980000x502560000", + "128880000x503640000", + GRN_DB_WGS84_GEO_POINT); +} + +static void +bench_setup_tgs(gpointer user_data) +{ + bench_setup_common(user_data); + bench_setup_points(user_data, + "127980000x502560000", + "128880000x503640000", + GRN_DB_TOKYO_GEO_POINT); +} + +static void +bench_setup_rectangular_wgs84(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_wgs84(user_data); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_tgs(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_tgs(user_data); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_1st_to_2nd_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "128452975x503157902", + "139380000x-31920000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_2nd_to_1st_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "139380000x-31920000", + "128452975x503157902", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_1st_to_3rd_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "128452975x503157902", + "-56880000x-172310000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_3rd_to_1st_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-56880000x-172310000", + "128452975x503157902", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_1st_to_4th_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "128452975x503157902", + "-122100000x66300000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_4th_to_1st_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-122100000x66300000", + "128452975x503157902", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_2nd_to_4th_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "139380000x-31920000", + "-122100000x66300000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_4th_to_2nd_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-122100000x66300000", + "139380000x-31920000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_1st_to_2nd_quadrant_long(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "128452975x503157902", + "135960000x-440760000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_2nd_to_1st_quadrant_long(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "135960000x-440760000", + "128452975x503157902", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_2nd_to_3rd_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "135960000x-440760000", + "-56880000x-172310000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_3rd_to_2nd_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-56880000x-172310000", + "135960000x-440760000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_3rd_to_4th_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-56880000x-172310000", + "-122100000x66300000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_4th_to_3rd_quadrant_short(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-122100000x66300000", + "-56880000x-172310000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_3rd_to_4th_quadrant_long(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-56880000x-172310000", + "-121926000x544351000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_rectangular_wgs84_4th_to_3rd_quadrant_long(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_common(user_data); + bench_setup_points(user_data, + "-121926000x544351000", + "-56880000x-172310000", + GRN_DB_WGS84_GEO_POINT); + data->geo_distance_proc = GET(data->context, "geo_distance"); +} + +static void +bench_setup_spherical_wgs84(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_wgs84(user_data); + data->geo_distance_proc = GET(data->context, "geo_distance2"); +} + +static void +bench_setup_spherical_tgs(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_tgs(user_data); + data->geo_distance_proc = GET(data->context, "geo_distance2"); +} + +static void +bench_setup_hubeny_wgs84(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_wgs84(user_data); + data->geo_distance_proc = GET(data->context, "geo_distance3"); +} + +static void +bench_setup_hubeny_tgs(gpointer user_data) +{ + BenchmarkData *data = user_data; + + bench_setup_tgs(user_data); + data->geo_distance_proc = GET(data->context, "geo_distance3"); +} + +static void +bench_teardown(gpointer user_data) +{ + BenchmarkData *data = user_data; + + if (data->report_result) { + grn_obj *result; + result = grn_expr_get_value(data->context, data->expression, 0); + g_print("result: %g\n", GRN_FLOAT_VALUE(result)); + /* http://vldb.gsi.go.jp/ says '38820.79' in WGS84 and + '38816.42' in Tokyo geodetic system for a distance + between '127980000x502560000' and '128880000x503640000'. */ + } + + grn_obj_unlink(data->context, data->end_point); + grn_obj_unlink(data->context, data->start_point); + grn_obj_unlink(data->context, data->expression); + grn_obj_unlink(data->context, data->database); + grn_ctx_fin(data->context); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchmarkData data; + BenchReporter *reporter; + gint n = 1000; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + data.report_result = g_getenv("GROONGA_BENCH_REPORT_RESULT") != NULL; + data.context = g_new(grn_ctx, 1); + + { + const gchar *groonga_bench_n; + groonga_bench_n = g_getenv("GROONGA_BENCH_N"); + if (groonga_bench_n) { + n = atoi(groonga_bench_n); + } + } + + reporter = bench_reporter_new(); + +#define REGISTER(label, setup) \ + bench_reporter_register(reporter, label, n, \ + bench_setup_ ## setup, \ + bench_geo_distance, \ + bench_teardown, \ + &data) + REGISTER("rectangular (WGS84)", rectangular_wgs84); + REGISTER("rectangular (TOKYO)", rectangular_tgs); + REGISTER("rectangular (WGS84 Tokyo to Lisbon)", + rectangular_wgs84_1st_to_2nd_quadrant_short); + REGISTER("rectangular (WGS84 Lisbon to Tokyo)", + rectangular_wgs84_2nd_to_1st_quadrant_short); + REGISTER("rectangular (WGS84 Tokyo to San Francisco)", + rectangular_wgs84_1st_to_2nd_quadrant_long); + REGISTER("rectangular (WGS84 San Francisco to Tokyo)", + rectangular_wgs84_2nd_to_1st_quadrant_long); + REGISTER("rectangular (WGS84 Brasplia to Cape Town)", + rectangular_wgs84_3rd_to_4th_quadrant_short); + REGISTER("rectangular (WGS84 Cape Town to Brasplia)", + rectangular_wgs84_4th_to_3rd_quadrant_short); + REGISTER("rectangular (WGS84 Brasplia to Sydney)", + rectangular_wgs84_3rd_to_4th_quadrant_long); + REGISTER("rectangular (WGS84 Sydney to Brasplia)", + rectangular_wgs84_4th_to_3rd_quadrant_long); + REGISTER("rectangular (WGS84 Tokyo to Brasplia)", + rectangular_wgs84_1st_to_4th_quadrant_short); + REGISTER("rectangular (WGS84 Brasplia to Tokyo)", + rectangular_wgs84_4th_to_1st_quadrant_short); + REGISTER("rectangular (WGS84 Lisbon to Cape Town)", + rectangular_wgs84_2nd_to_3rd_quadrant_short); + REGISTER("rectangular (WGS84 Cape Town to Lisbon)", + rectangular_wgs84_3rd_to_2nd_quadrant_short); + REGISTER("rectangular (WGS84 Tokyo to Cape Town)", + rectangular_wgs84_1st_to_3rd_quadrant_short); + REGISTER("rectangular (WGS84 Cape Town to Tokyo)", + rectangular_wgs84_3rd_to_1st_quadrant_short); + REGISTER("rectangular (WGS84 Lisbon to Cape Town)", + rectangular_wgs84_2nd_to_4th_quadrant_short); + REGISTER("rectangular (WGS84 Cape Town to Lisbon)", + rectangular_wgs84_4th_to_2nd_quadrant_short); + REGISTER("spherical (WGS84)", spherical_wgs84); + REGISTER("spherical (TOKYO)", spherical_tgs); + REGISTER("hubeny (WGS84)", hubeny_wgs84); + REGISTER("hubeny (TOKYO)", hubeny_tgs); +#undef REGISTER + + bench_reporter_run(reporter); + g_object_unref(reporter); + + g_free(data.context); + + bench_quit(); + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c new file mode 100644 index 00000000..dcad47fd --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c @@ -0,0 +1,276 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2011-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + groonga: f56f466a05d756336f26ea5c2e54e9bdf5d3d681 + CFLAGS: -O0 -ggdb3 + CPU: Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz stepping 05 + % (cd test/benchmark/ && make --quiet run-bench-geo-select) + run-bench-geo-select: + (time) + 1st: select_in_rectangle (partial): (0.819828) + 2nd: select_in_rectangle (partial): (0.832293) + 1st: select_in_rectangle (all): (8.82504) + 2nd: select_in_rectangle (all): (8.97628) + + % (cd test/benchmark; GRN_GEO_CURSOR_STRICTLY=yes make --quiet run-bench-geo-select) + run-bench-geo-select: + (time) + 1st: select_in_rectangle (partial): (0.528143) + 2nd: select_in_rectangle (partial): (0.518647) + 1st: select_in_rectangle (all): (8.77378) + 2nd: select_in_rectangle (all): (8.76765) + + groonga: f56f466a05d756336f26ea5c2e54e9bdf5d3d681 + CFLAGS: -O3 -ggdb3 + CPU: Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz stepping 05 + % (cd test/benchmark/ && make --quiet run-bench-geo-select) + run-bench-geo-select: + (time) + 1st: select_in_rectangle (partial): (0.415439) + 2nd: select_in_rectangle (partial): (0.423479) + 1st: select_in_rectangle (all): (4.63983) + 2nd: select_in_rectangle (all): (4.53055) + + % (cd test/benchmark; GRN_GEO_CURSOR_STRICTLY=yes make --quiet run-bench-geo-select) + run-bench-geo-select: + (time) + 1st: select_in_rectangle (partial): (0.26974) + 2nd: select_in_rectangle (partial): (0.250247) + 1st: select_in_rectangle (all): (4.45263) + 2nd: select_in_rectangle (all): (4.61558) +*/ + +#include <stdlib.h> +#include <string.h> + +#include <grn_db.h> +#include <groonga.h> + +#include "lib/benchmark.h" + +#define GET(context, name) (grn_ctx_get(context, name, strlen(name))) + +typedef struct _BenchmarkData +{ + gboolean report_result; + + grn_ctx *context; + grn_obj *database; + grn_obj *table; + grn_obj *index_column; + grn_obj *result; + + grn_obj top_left_point; + grn_obj bottom_right_point; +} BenchmarkData; + +static void +set_geo_point(grn_ctx *context, grn_obj *geo_point, const gchar *geo_point_text) +{ + grn_obj point_text; + + GRN_TEXT_INIT(&point_text, 0); + GRN_TEXT_PUTS(context, &point_text, geo_point_text); + grn_obj_cast(context, &point_text, geo_point, GRN_FALSE); + grn_obj_unlink(context, &point_text); +} + +static void +bench_setup_common(gpointer user_data) +{ + BenchmarkData *data = user_data; + const gchar *tokyo_station = "35.68136,139.76609"; + const gchar *ikebukuro_station = "35.72890,139.71036"; + + data->result = grn_table_create(data->context, NULL, 0, NULL, + GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC, + data->table, NULL); + + set_geo_point(data->context, &(data->top_left_point), + ikebukuro_station); + set_geo_point(data->context, &(data->bottom_right_point), + tokyo_station); +} + +static void +bench_setup_query_partial(gpointer user_data) +{ + BenchmarkData *data = user_data; + const gchar *tokyo_station = "35.68136,139.76609"; + const gchar *ikebukuro_station = "35.72890,139.71036"; + + set_geo_point(data->context, &(data->top_left_point), + ikebukuro_station); + set_geo_point(data->context, &(data->bottom_right_point), + tokyo_station); +} + +static void +bench_setup_query_all(gpointer user_data) +{ + BenchmarkData *data = user_data; + const gchar *tokyo_station = "35.0,140.0"; + const gchar *ikebukuro_station = "36.0,139.0"; + + set_geo_point(data->context, &(data->top_left_point), + ikebukuro_station); + set_geo_point(data->context, &(data->bottom_right_point), + tokyo_station); +} + +static void +bench_setup_in_rectangle_partial(gpointer user_data) +{ + bench_setup_common(user_data); + bench_setup_query_partial(user_data); +} + +static void +bench_setup_in_rectangle_all(gpointer user_data) +{ + bench_setup_common(user_data); + bench_setup_query_all(user_data); +} + +static void +bench_geo_select_in_rectangle(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_geo_select_in_rectangle(data->context, + data->index_column, + &(data->top_left_point), + &(data->bottom_right_point), + data->result, + GRN_OP_OR); +} + +static void +bench_teardown(gpointer user_data) +{ + BenchmarkData *data = user_data; + + if (data->report_result) { + g_print("result: %d\n", grn_table_size(data->context, data->result)); + } + + grn_obj_unlink(data->context, data->result); +} + +static gchar * +get_tmp_dir(void) +{ + gchar *current_dir; + gchar *tmp_dir; + + current_dir = g_get_current_dir(); + tmp_dir = g_build_filename(current_dir, "tmp", NULL); + g_free(current_dir); + + return tmp_dir; +} + +static void +setup_database(BenchmarkData *data) +{ + gchar *tmp_dir; + gchar *database_path; + + tmp_dir = get_tmp_dir(); + database_path = g_build_filename(tmp_dir, "geo-select", "db", NULL); + data->database = grn_db_open(data->context, database_path); + + data->table = GET(data->context, "Addresses"); + data->index_column = GET(data->context, "Locations.address"); + + g_free(database_path); +} + +static void +teardown_database(BenchmarkData *data) +{ + grn_obj_unlink(data->context, data->index_column); + grn_obj_unlink(data->context, data->table); + grn_obj_unlink(data->context, data->database); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchmarkData data; + BenchReporter *reporter; + gint n = 100; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + data.report_result = g_getenv("GROONGA_BENCH_REPORT_RESULT") != NULL; + + data.context = g_new(grn_ctx, 1); + grn_ctx_init(data.context, 0); + + setup_database(&data); + GRN_WGS84_GEO_POINT_INIT(&(data.top_left_point), 0); + GRN_WGS84_GEO_POINT_INIT(&(data.bottom_right_point), 0); + + { + const gchar *groonga_bench_n; + groonga_bench_n = g_getenv("GROONGA_BENCH_N"); + if (groonga_bench_n) { + n = atoi(groonga_bench_n); + } + } + + reporter = bench_reporter_new(); + +#define REGISTER(label, type, area) \ + bench_reporter_register(reporter, \ + label, \ + n, \ + bench_setup_ ## type ## _ ## area, \ + bench_geo_select_ ## type, \ + bench_teardown, \ + &data) + REGISTER("1st: select_in_rectangle (partial)", in_rectangle, partial); + REGISTER("2nd: select_in_rectangle (partial)", in_rectangle, partial); + REGISTER("1st: select_in_rectangle (all)", in_rectangle, all); + REGISTER("2nd: select_in_rectangle (all)", in_rectangle, all); +#undef REGISTER + + bench_reporter_run(reporter); + g_object_unref(reporter); + + grn_obj_unlink(data.context, &(data.top_left_point)); + grn_obj_unlink(data.context, &(data.bottom_right_point)); + teardown_database(&data); + + grn_ctx_fin(data.context); + g_free(data.context); + + bench_quit(); + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.sh b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.sh new file mode 100755 index 00000000..7e84c8fc --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +base_dir="$(dirname $0)" + +fixture_dir="${srcdir}/fixtures/geo-select" +data_dir="${base_dir}/fixtures/geo-select" +csv_xz="${fixture_dir}/13_2010.CSV.xz" +csv="${data_dir}/13_2010.CSV" +grn="${data_dir}/load.grn" + +geo_select_generate_grn_rb="${base_dir}/geo-select-generate-grn.rb" + +db="${base_dir}/tmp/geo-select/db" + +bench_geo_select="./bench-geo-select" + +mkdir -p "${data_dir}" +if [ ! -s "${csv}" ] || [ "${csv}" -ot "${csv_xz}" ]; then + echo "extracting ${csv_xz}..." + xzcat "${csv_xz}" | iconv --from-code cp932 --to-code utf-8 > "${csv}" +fi + +if [ ! -s "${grn}" ] || [ "${grn}" -ot "${csv}" ]; then + echo "generating test data..." + "${RUBY}" "${geo_select_generate_grn_rb}" "${csv}" "${grn}" +fi + +if [ ! -s "${db}" ] || [ "${db}" -ot "${grn}" ]; then + echo "creating test database..." + rm -rf "$(dirname ${db})" + mkdir -p "$(dirname ${db})" + "${GROONGA}" -n "${db}" < "${grn}" +fi + +if [ "${GROONGA_BENCH_DEBUG}" = "yes" ]; then + bench_geo_select="../../libtool --mode=execute gdb --args ${bench_geo_select}" +fi +${bench_geo_select} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c b/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c new file mode 100644 index 00000000..ebae95b2 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c @@ -0,0 +1,275 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + Groonga: ed300a833d44eaefa978b5ecf46a96ef91ae0891 + + CFLAGS: -O2 -g + % make --quiet -C benchmark run-bench-nfkc + run-bench-nfkc: + (total) (average) (median) + map1 - switch : (0.0060ms) (0.00060000ms) (0.00000000ms) + map1 - table : (0.00000000ms) (0.00000000ms) (0.00000000ms) + map2 - switch - no change: (0.0010ms) (0.00010000ms) (0.00000000ms) + map2 - table - no change: (0.00000000ms) (0.00000000ms) (0.00000000ms) + map2 - switch - change: (0.0010ms) (0.00010000ms) (0.00000000ms) + map2 - table - change: (0.0010ms) (0.00010000ms) (0.00000000ms) +*/ + +#include <stdlib.h> +#include <stdio.h> + +#include <glib.h> + +#include <groonga.h> + +#include "lib/benchmark.h" + +#include "../lib/nfkc50.c" + +#define MAX_UNICODE 0x110000 +#define BUFFER_SIZE 0x100 + +static inline int +ucs2utf8(unsigned int i, unsigned char *buf) +{ + unsigned char *p = buf; + if (i < 0x80) { + *p++ = i; + } else { + if (i < 0x800) { + *p++ = (i >> 6) | 0xc0; + } else { + if (i < 0x00010000) { + *p++ = (i >> 12) | 0xe0; + } else { + if (i < 0x00200000) { + *p++ = (i >> 18) | 0xf0; + } else { + if (i < 0x04000000) { + *p++ = (i >> 24) | 0xf8; + } else if (i < 0x80000000) { + *p++ = (i >> 30) | 0xfc; + *p++ = ((i >> 24) & 0x3f) | 0x80; + } + *p++ = ((i >> 18) & 0x3f) | 0x80; + } + *p++ = ((i >> 12) & 0x3f) | 0x80; + } + *p++ = ((i >> 6) & 0x3f) | 0x80; + } + *p++ = (0x3f & i) | 0x80; + } + *p = '\0'; + return (p - buf); +} + +static void +bench_char_type(gpointer user_data) +{ + uint64_t code_point; + char utf8[7]; + + for (code_point = 1; code_point < MAX_UNICODE; code_point++) { + ucs2utf8(code_point, (unsigned char *)utf8); + grn_nfkc50_char_type(utf8); + } +} + +static void +bench_decompose(gpointer user_data) +{ + uint64_t code_point; + char utf8[7]; + + for (code_point = 1; code_point < MAX_UNICODE; code_point++) { + ucs2utf8(code_point, (unsigned char *)utf8); + grn_nfkc50_decompose(utf8); + } +} + +static void +bench_compose_no_change(gpointer user_data) +{ + uint64_t prefix_code_point; + uint64_t suffix_code_point = 0x61; /* a */ + char prefix_utf8[7]; + char suffix_utf8[7]; + + ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8); + for (prefix_code_point = 1; + prefix_code_point < MAX_UNICODE; + prefix_code_point++) { + ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8); + grn_nfkc50_compose(prefix_utf8, suffix_utf8); + } +} + +static void +bench_compose_change(gpointer user_data) +{ + uint64_t prefix_code_point; + uint64_t suffix_code_point = 0x11ba; + char prefix_utf8[7]; + char suffix_utf8[7]; + + ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8); + for (prefix_code_point = 1; + prefix_code_point < MAX_UNICODE; + prefix_code_point++) { + ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8); + grn_nfkc50_compose(prefix_utf8, suffix_utf8); + } +} + +/* +static void +check_char_type(gpointer user_data) +{ + uint64_t code_point; + char utf8[7]; + + for (code_point = 1; code_point < MAX_UNICODE; code_point++) { + grn_char_type a; + grn_char_type b; + + ucs2utf8(code_point, (unsigned char *)utf8); + a = grn_nfkc_char_type(utf8); + b = grn_nfkc50_char_type(utf8); + if (a == b) { + continue; + } + printf("%lx: %s: %d != %d\n", code_point, utf8, a, b); + } +} + +static void +check_decompose(gpointer user_data) +{ + uint64_t code_point; + char utf8[7]; + + for (code_point = 1; code_point < MAX_UNICODE; code_point++) { + const char *a; + const char *b; + + ucs2utf8(code_point, (unsigned char *)utf8); + a = grn_nfkc_decompose(utf8); + b = grn_nfkc50_decompose(utf8); + if (a == b) { + continue; + } + if (!a || !b) { + printf("%lx: %s: %s != %s\n", code_point, utf8, a, b); + continue; + } + if (strcmp(a, b) != 0) { + printf("%lx: %s: %s != %s\n", code_point, utf8, a, b); + } + } +} + +static void +check_compose(gpointer user_data) +{ + uint64_t prefix_code_point; + uint64_t suffix_code_point; + char prefix_utf8[7]; + char suffix_utf8[7]; + + for (prefix_code_point = 1; + prefix_code_point < MAX_UNICODE; + prefix_code_point++) { + ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8); + for (suffix_code_point = 1; + suffix_code_point < MAX_UNICODE; + suffix_code_point++) { + const char *a; + const char *b; + + ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8); + a = grn_nfkc_compose(prefix_utf8, suffix_utf8); + b = grn_nfkc50_compose(prefix_utf8, suffix_utf8); + if (a == b) { + continue; + } + if (!a || !b) { + printf("%lx-%lx: %s-%s: %s != %s\n", + prefix_code_point, suffix_code_point, + prefix_utf8, suffix_utf8, + a, b); + continue; + } + if (strcmp(a, b) != 0) { + printf("%lx-%lx: %s-%s: %s != %s\n", + prefix_code_point, suffix_code_point, + prefix_utf8, suffix_utf8, + a, b); + } + } + if ((prefix_code_point % 10000) == 0) { + printf("%" G_GUINT64_FORMAT "\n", prefix_code_point); + } + } +} +*/ + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchReporter *reporter; + gint n = 10; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + reporter = bench_reporter_new(); + + if (g_getenv("N")) { + n = atoi(g_getenv("N")); + } + +#define REGISTER(label, bench_function) \ + bench_reporter_register(reporter, label, n, \ + NULL, \ + bench_function, \ + NULL, \ + NULL) + REGISTER("char_type ", bench_char_type); + REGISTER("decompose ", bench_decompose); + REGISTER("compose - no change", bench_compose_no_change); + REGISTER("compose - change", bench_compose_change); + + /* + REGISTER("check - char_type", check_char_type); + REGISTER("check - decompose", check_decompose); + REGISTER("check - compose ", check_compose); + */ +#undef REGISTER + + bench_reporter_run(reporter); + g_object_unref(reporter); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer-ddl.grn b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer-ddl.grn new file mode 100644 index 00000000..68317ae9 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer-ddl.grn @@ -0,0 +1,16 @@ +table_create Entries TABLE_PAT_KEY ShortText +column_create Entries name COLUMN_SCALAR ShortText +column_create Entries description COLUMN_SCALAR Text +column_create Entries last_modified COLUMN_SCALAR Time + +table_create Bigram TABLE_PAT_KEY ShortText \ + --default_tokenizer TokenBigram \ + --normalizer NormalizerAuto +column_create Bigram entries_name COLUMN_INDEX|WITH_POSITION \ + Entries name +column_create Bigram entries_description COLUMN_INDEX|WITH_POSITION \ + Entries description + +table_create Times TABLE_PAT_KEY Time +column_create Times entries_last_modified COLUMN_INDEX \ + Entries last_modified diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c new file mode 100644 index 00000000..48c2cb0f --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c @@ -0,0 +1,214 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2014-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + Groonga: c4379140c02699e3c74b94cd9e7b88d372202aa5 + + CFLAGS: -O0 -g3 + % make --quiet -C benchmark run-bench-query-optimizer + run-bench-query-optimizer: + Process 100 times in each pattern + (time) + 1 condition: with mruby: (0.0362s) + 1 condition: without mruby: (0.0216s) + 4 conditions: with mruby: (0.0864s) + 4 conditions: without mruby: (0.0271s) + + CFLAGS: -O2 -g + % make --quiet -C benchmark run-bench-query-optimizer + run-bench-query-optimizer: + Process 100 times in each pattern + (time) + 1 condition: with mruby: (0.0243s) + 1 condition: without mruby: (0.0159s) + 4 conditions: with mruby: (0.0452s) + 4 conditions: without mruby: (0.0188s) +*/ + +#include <stdlib.h> +#include <string.h> + +#include <glib.h> + +#include <groonga.h> + +#include "lib/benchmark.h" + +typedef struct _BenchmarkData { + grn_ctx context; + grn_obj *database; + grn_bool use_mruby; + GString *command; +} BenchmarkData; + +static void +bench(gpointer user_data) +{ + BenchmarkData *data = user_data; + grn_ctx *context = &(data->context); + char *response; + unsigned int response_length; + int flags; + + grn_ctx_send(context, data->command->str, data->command->len, 0); + grn_ctx_recv(context, &response, &response_length, &flags); +} + +static void +bench_setup(gpointer user_data) +{ + BenchmarkData *data = user_data; + + if (data->use_mruby) { + g_setenv("GRN_MRUBY_ENABLED", "yes", TRUE); + } else { + g_setenv("GRN_MRUBY_ENABLED", "no", TRUE); + } + grn_ctx_init(&(data->context), 0); + grn_ctx_use(&(data->context), data->database); +} + +static void +bench_teardown(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_ctx_fin(&(data->context)); +} + +static gchar * +get_tmp_dir(void) +{ + gchar *current_dir; + gchar *tmp_dir; + + current_dir = g_get_current_dir(); + tmp_dir = g_build_filename(current_dir, "tmp", NULL); + g_free(current_dir); + + return tmp_dir; +} + +static grn_obj * +setup_database(grn_ctx *context) +{ + gchar *tmp_dir; + gchar *database_path; + grn_obj *database; + const gchar *warmup_command = "dump"; + gchar *response; + unsigned int response_length; + int flags; + + tmp_dir = get_tmp_dir(); + database_path = g_build_filename(tmp_dir, "query-optimizer", "db", NULL); + database = grn_db_open(context, database_path); + grn_ctx_send(context, warmup_command, strlen(warmup_command), 0); + grn_ctx_recv(context, &response, &response_length, &flags); + + g_free(database_path); + + return database; +} + +static void +teardown_database(grn_ctx *context, grn_obj *database) +{ + grn_obj_close(context, database); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + grn_ctx context; + grn_obj *database; + BenchReporter *reporter; + gint n = 100; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + grn_ctx_init(&context, 0); + + database = setup_database(&context); + + reporter = bench_reporter_new(); + + g_print("Process %d times in each pattern\n", n); + { + BenchmarkData data_one_condition_with_mruby; + BenchmarkData data_one_condition_without_mruby; + BenchmarkData data_multiple_conditions_with_mruby; + BenchmarkData data_multiple_conditions_without_mruby; + +#define REGISTER(label, data, use_mruby_, command_) \ + data.database = database; \ + data.use_mruby = use_mruby_; \ + data.command = g_string_new(command_); \ + bench_reporter_register(reporter, label, \ + n, \ + bench_setup, \ + bench, \ + bench_teardown, \ + &data) + + REGISTER("1 condition: with mruby", data_one_condition_with_mruby, + GRN_TRUE, + "select Entries --cache no --query 'name:@Groonga'"); + REGISTER("1 condition: without mruby", data_one_condition_without_mruby, + GRN_FALSE, + "select Entries --cache no --query 'name:@Groonga'"); + REGISTER("4 conditions: with mruby", + data_multiple_conditions_with_mruby, + GRN_TRUE, + "select Entries --cache no --filter '" + "name @ \"Groonga\" && " + "description @ \"search\" && " + "last_modified >= \"2014-2-9 00:00:00\" && " + "last_modified <= \"2014-11-29 00:00:00\"" + "'"); + REGISTER("4 conditions: without mruby", + data_multiple_conditions_without_mruby, + GRN_FALSE, + "select Entries --cache no --filter '" + "name @ \"Groonga\" && " + "description @ \"search\" && " + "last_modified >= \"2014-2-9 00:00:00\" && " + "last_modified <= \"2014-11-29 00:00:00\"" + "'"); + +#undef REGISTER + + bench_reporter_run(reporter); + } + g_object_unref(reporter); + + teardown_database(&context, database); + + grn_ctx_fin(&context); + + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c new file mode 100644 index 00000000..11df9c10 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c @@ -0,0 +1,280 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2014-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +/* + Groonga: 09a4c4e00832fb90dee74c5b97b7cf0f5952f85b + + CPU Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz (fam: 06, model: 1e, stepping: 05) + + CFLAGS: -O0 -g3 + % make --quiet -C benchmark run-bench-range-select + run-bench-range-select: + Process 10 times in each pattern + (total) (average) (median) + ( 500, 600] ( 1000): with mruby: (0.0058s) (0.5773ms) (0.5830ms) + ( 500, 600] ( 1000): without mruby: (0.0062s) (0.6203ms) (0.6200ms) + ( 5000, 5100] ( 10000): with mruby: (0.0058s) (0.5827ms) (0.5800ms) + ( 5000, 5100] ( 10000): without mruby: (0.0473s) (0.0047s) (0.0048s) + ( 50000, 50100] ( 100000): with mruby: (0.0064s) (0.6397ms) (0.6370ms) + ( 50000, 50100] ( 100000): without mruby: (0.4498s) (0.0450s) (0.0442s) + (500000, 500100] (1000000): with mruby: (0.0057s) (0.5710ms) (0.5190ms) + (500000, 500100] (1000000): without mruby: (4.3193s) (0.4319s) (0.4306s) + + CFLAGS: -O2 -g + % make --quiet -C benchmark run-bench-range-select + run-bench-range-select: + Process 10 times in each pattern + (total) (average) (median) + ( 500, 600] ( 1000): with mruby: (0.0031s) (0.3058ms) (0.2890ms) + ( 500, 600] ( 1000): without mruby: (0.0031s) (0.3132ms) (0.3090ms) + ( 5000, 5100] ( 10000): with mruby: (0.0031s) (0.3063ms) (0.3100ms) + ( 5000, 5100] ( 10000): without mruby: (0.0239s) (0.0024s) (0.0023s) + ( 50000, 50100] ( 100000): with mruby: (0.0028s) (0.2825ms) (0.2660ms) + ( 50000, 50100] ( 100000): without mruby: (0.2117s) (0.0212s) (0.0211s) + (500000, 500100] (1000000): with mruby: (0.0028s) (0.2757ms) (0.2650ms) + (500000, 500100] (1000000): without mruby: (2.0874s) (0.2087s) (0.2092s) +*/ + +#include <stdio.h> +#include <string.h> + +#include <grn_db.h> +#include <groonga.h> + +#include "lib/benchmark.h" + +#define GET(context, name) (grn_ctx_get(context, name, strlen(name))) + +typedef struct _BenchmarkData +{ + grn_ctx context; + grn_obj *database; + guint n_records; + grn_bool use_mruby; + const gchar *command; +} BenchmarkData; + +static void +run_command(grn_ctx *context, const gchar *command) +{ + gchar *response; + unsigned int response_length; + int flags; + + grn_ctx_send(context, command, strlen(command), 0); + grn_ctx_recv(context, &response, &response_length, &flags); +} + +static void +bench(gpointer user_data) +{ + BenchmarkData *data = user_data; + grn_ctx *context = &(data->context); + + run_command(context, data->command); +} + +static gchar * +get_tmp_dir(void) +{ + gchar *current_dir; + gchar *tmp_dir; + + current_dir = g_get_current_dir(); + tmp_dir = g_build_filename(current_dir, "tmp", NULL); + g_free(current_dir); + + return tmp_dir; +} + +static void +setup_database(BenchmarkData *data) +{ + grn_ctx *context = &(data->context); + gchar *tmp_dir; + gchar *database_last_component_name; + gchar *database_path; + guint i; + + tmp_dir = get_tmp_dir(); + database_last_component_name = + g_strdup_printf("db-%d-%s-mruby", + data->n_records, + data->use_mruby ? "with" : "without"); + database_path = g_build_filename(tmp_dir, + "range-select", + database_last_component_name, + NULL); + g_free(database_last_component_name); + + if (g_file_test(database_path, G_FILE_TEST_EXISTS)) { + data->database = grn_db_open(context, database_path); + run_command(context, "dump"); + } else { + data->database = grn_db_create(context, database_path, NULL); + + run_command(context, "table_create Entries TABLE_NO_KEY"); + run_command(context, "column_create Entries rank COLUMN_SCALAR Int32"); + run_command(context, "table_create Ranks TABLE_PAT_KEY Int32"); + run_command(context, + "column_create Ranks entries_rank COLUMN_INDEX Entries rank"); + + run_command(context, "load --table Entries"); + run_command(context, "["); + for (i = 0; i < data->n_records; i++) { +#define BUFFER_SIZE 4096 + gchar buffer[BUFFER_SIZE]; + const gchar *separator; + if (i == (data->n_records - 1)) { + separator = ""; + } else { + separator = ","; + } + snprintf(buffer, BUFFER_SIZE, "{\"rank\": %u}%s", i, separator); + run_command(context, buffer); +#undef BUFFER_SIZE + } + run_command(context, "]"); + } + + g_free(database_path); +} + +static void +bench_startup(BenchmarkData *data) +{ + if (data->use_mruby) { + g_setenv("GRN_MRUBY_ENABLED", "yes", TRUE); + } else { + g_setenv("GRN_MRUBY_ENABLED", "no", TRUE); + } + grn_ctx_init(&(data->context), 0); + setup_database(data); +} + +static void +bench_shutdown(BenchmarkData *data) +{ + grn_ctx *context = &(data->context); + + grn_obj_close(context, data->database); + grn_ctx_fin(context); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchReporter *reporter; + gint n = 10; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + + g_print("Process %d times in each pattern\n", n); + + bench_init(&argc, &argv); + reporter = bench_reporter_new(); + + { + BenchmarkData data_small_with_mruby; + BenchmarkData data_small_without_mruby; + BenchmarkData data_medium_with_mruby; + BenchmarkData data_medium_without_mruby; + BenchmarkData data_large_with_mruby; + BenchmarkData data_large_without_mruby; + BenchmarkData data_very_large_with_mruby; + BenchmarkData data_very_large_without_mruby; + +#define REGISTER(data, n_records_, min, max, use_mruby_) \ + do { \ + gchar *label; \ + label = g_strdup_printf("(%6d, %6d] (%7d): %7s mruby", \ + min, max, n_records_, \ + use_mruby_ ? "with" : "without"); \ + data.use_mruby = use_mruby_; \ + data.n_records = n_records_; \ + data.command = \ + "select Entries --cache no " \ + "--filter 'rank > " #min " && rank <= " #max "'"; \ + bench_startup(&data); \ + bench_reporter_register(reporter, label, \ + n, \ + NULL, \ + bench, \ + NULL, \ + &data); \ + g_free(label); \ + } while(FALSE) + + REGISTER(data_small_with_mruby, + 1000, + 500, 600, + GRN_TRUE); + REGISTER(data_small_without_mruby, + 1000, + 500, 600, + GRN_FALSE); + REGISTER(data_medium_with_mruby, + 10000, + 5000, 5100, + GRN_TRUE); + REGISTER(data_medium_without_mruby, + 10000, + 5000, 5100, + GRN_FALSE); + REGISTER(data_large_with_mruby, + 100000, + 50000, 50100, + GRN_TRUE); + REGISTER(data_large_without_mruby, + 100000, + 50000, 50100, + GRN_FALSE); + REGISTER(data_very_large_with_mruby, + 1000000, + 500000, 500100, + GRN_TRUE); + REGISTER(data_very_large_without_mruby, + 1000000, + 500000, 500100, + GRN_FALSE); + +#undef REGISTER + + bench_reporter_run(reporter); + + bench_shutdown(&data_small_with_mruby); + bench_shutdown(&data_small_without_mruby); + bench_shutdown(&data_medium_with_mruby); + bench_shutdown(&data_medium_without_mruby); + bench_shutdown(&data_large_with_mruby); + bench_shutdown(&data_large_without_mruby); + bench_shutdown(&data_very_large_with_mruby); + bench_shutdown(&data_very_large_without_mruby); + } + g_object_unref(reporter); + + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c b/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c new file mode 100644 index 00000000..bba5baea --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c @@ -0,0 +1,151 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#include <string.h> +#include <stdlib.h> + +#include <groonga.h> + +#include "lib/benchmark.h" + +typedef struct _BenchmarkData +{ + gchar *base_dir; + grn_ctx *context; + grn_obj *source_table; + grn_obj *result_set; +} BenchmarkData; + +static void +bench_n(BenchmarkData *data, gint64 n) +{ + gint64 i; + grn_ctx *ctx; + grn_hash *result_set; + + ctx = data->context; + result_set = (grn_hash *)data->result_set; + for (i = 0; i < n; i++) { + grn_id id = i; + grn_hash_add(ctx, result_set, &id, sizeof(grn_id), NULL, NULL); + } +} + +static void +bench_1000(gpointer user_data) +{ + BenchmarkData *data = user_data; + bench_n(data, 1000); +} + +static void +bench_10000(gpointer user_data) +{ + BenchmarkData *data = user_data; + bench_n(data, 10000); +} + +static void +bench_100000(gpointer user_data) +{ + BenchmarkData *data = user_data; + bench_n(data, 100000); +} + +static void +bench_setup(gpointer user_data) +{ + BenchmarkData *data = user_data; + + data->result_set = grn_table_create(data->context, + NULL, 0, NULL, + GRN_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC, + data->source_table, + NULL); + +} + +static void +bench_teardown(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_obj_close(data->context, data->result_set); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchmarkData data; + BenchReporter *reporter; + gchar *base_dir; + grn_ctx ctx; + gint n = 100; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + data.context = &ctx; + + base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL); + bench_utils_remove_path_recursive_force(base_dir); + g_mkdir_with_parents(base_dir, 0755); + + { + gchar *database_path; + const gchar *source_table_name = "Sources"; + + grn_ctx_init(&ctx, 0); + database_path = g_build_filename(base_dir, "db", NULL); + grn_db_create(&ctx, database_path, NULL); + g_free(database_path); + + data.source_table = grn_table_create(&ctx, + source_table_name, + strlen(source_table_name), + NULL, + GRN_TABLE_PAT_KEY | GRN_OBJ_PERSISTENT, + grn_ctx_at(&ctx, GRN_DB_SHORT_TEXT), + NULL); + } + + reporter = bench_reporter_new(); + bench_reporter_register(reporter, "1000", n, + bench_setup, bench_1000, bench_teardown, &data); + bench_reporter_register(reporter, "10000", n, + bench_setup, bench_10000, bench_teardown, &data); + bench_reporter_register(reporter, "100000", n, + bench_setup, bench_100000, bench_teardown, &data); + bench_reporter_run(reporter); + g_object_unref(reporter); + + grn_ctx_fin(&ctx); + + bench_utils_remove_path_recursive_force(data.base_dir); + + bench_quit(); + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c b/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c new file mode 100644 index 00000000..025b0750 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c @@ -0,0 +1,277 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2008-2016 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#include <string.h> +#include <stdlib.h> + +#include <groonga.h> + +#include "lib/benchmark.h" + +#define DEFAULT_FLAGS (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_PAT_KEY) +#define DEFAULT_VALUE_SIZE (1024) +#define VALUE_TYPE_NAME "<value_type>" + +typedef struct _BenchmarkData +{ + gchar *base_dir; + + grn_ctx *context; + const char *name; + unsigned name_size; + char *path; + grn_obj_flags flags; + grn_obj *key_type; + unsigned value_size; + grn_encoding encoding; +} BenchmarkData; + +static void +bench_normal(gpointer user_data) +{ + BenchmarkData *data = user_data; + grn_obj *table; + grn_obj *value_type = grn_ctx_get(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME)); + if (!value_type) { + value_type = grn_type_create(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME), + 0, data->value_size); + } + table = grn_table_create(data->context, + data->name, data->name_size, + data->path, data->flags, + data->key_type, value_type); + grn_obj_close(data->context, table); +} + +static void +bench_normal_temporary(gpointer user_data) +{ + BenchmarkData *data = user_data; + grn_obj *table; + grn_obj *value_type = grn_ctx_get(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME)); + if (!value_type) { + value_type = grn_type_create(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME), + 0, data->value_size); + } + GRN_CTX_SET_ENCODING(data->context, data->encoding); + table = grn_table_create(data->context, + data->name, data->name_size, + NULL, data->flags & ~GRN_OBJ_PERSISTENT, + data->key_type, value_type); + grn_obj_close(data->context, table); +} + +typedef struct _grn_table_factory +{ + grn_ctx *context; + char *name; + unsigned name_size; + char *path; + grn_obj_flags flags; + grn_obj *key_type; + unsigned value_size; + grn_encoding encoding; +} grn_table_factory; + +static grn_table_factory * +grn_table_factory_create(void) +{ + grn_table_factory *factory; + + factory = g_new0(grn_table_factory, 1); + + factory->context = NULL; + factory->name = NULL; + factory->name_size = 0; + factory->path = NULL; + factory->flags = DEFAULT_FLAGS; + factory->key_type = NULL; + factory->value_size = DEFAULT_VALUE_SIZE; + factory->encoding = GRN_ENC_DEFAULT; + + return factory; +} + +static void +grn_table_factory_set_context(grn_table_factory *factory, grn_ctx *context) +{ + factory->context = context; +} + +static void +grn_table_factory_set_name(grn_table_factory *factory, const char *name) +{ + factory->name = g_strdup(name); + factory->name_size = strlen(name); +} + +static void +grn_table_factory_set_path(grn_table_factory *factory, const char *path) +{ + factory->path = g_strdup(path); + if (path) + factory->flags |= GRN_OBJ_PERSISTENT; + else + factory->flags &= ~GRN_OBJ_PERSISTENT; +} + +static void +grn_table_factory_set_key_type(grn_table_factory *factory, grn_obj *key_type) +{ + factory->key_type = key_type; +} + +static grn_obj * +grn_table_factory_make(grn_table_factory *factory) +{ + grn_obj *value_type = grn_ctx_get(factory->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME)); + if (!value_type) { + value_type = grn_type_create(factory->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME), + 0, factory->value_size); + } + GRN_CTX_SET_ENCODING(factory->context, factory->encoding); + return grn_table_create(factory->context, + factory->name, factory->name_size, + factory->path, factory->flags, + factory->key_type, value_type); +} + +static void +grn_table_factory_close(grn_table_factory *factory) +{ + g_free(factory->name); + g_free(factory->path); + g_free(factory); +} + +static void +bench_factory(gpointer user_data) +{ + BenchmarkData *data = user_data; + grn_table_factory *factory; + grn_obj *table; + + factory = grn_table_factory_create(); + grn_table_factory_set_context(factory, data->context); + grn_table_factory_set_name(factory, data->name); + grn_table_factory_set_path(factory, data->path); + grn_table_factory_set_key_type(factory, data->key_type); + + table = grn_table_factory_make(factory); + grn_obj_close(data->context, table); + + grn_table_factory_close(factory); +} + +static void +bench_factory_temporary(gpointer user_data) +{ + BenchmarkData *data = user_data; + grn_table_factory *factory; + grn_obj *table; + + factory = grn_table_factory_create(); + grn_table_factory_set_context(factory, data->context); + grn_table_factory_set_name(factory, data->name); + grn_table_factory_set_key_type(factory, data->key_type); + + table = grn_table_factory_make(factory); + grn_obj_close(data->context, table); + + grn_table_factory_close(factory); +} + +static void +bench_setup(gpointer user_data) +{ + BenchmarkData *data = user_data; + const gchar *type_name; + + bench_utils_remove_path_recursive_force(data->base_dir); + g_mkdir_with_parents(data->base_dir, 0755); + + grn_ctx_init(data->context, GRN_CTX_USE_QL); + + type_name = "name"; + data->key_type = grn_type_create(data->context, + type_name, strlen(type_name), + GRN_OBJ_KEY_UINT, sizeof(grn_id)); + +} + +static void +bench_teardown(gpointer user_data) +{ + BenchmarkData *data = user_data; + + grn_obj_close(data->context, data->key_type); + grn_ctx_fin(data->context); + bench_utils_remove_path_recursive_force(data->base_dir); +} + +int +main(int argc, gchar **argv) +{ + grn_rc rc; + BenchmarkData data; + BenchReporter *reporter; + gint n = 100; + + rc = grn_init(); + if (rc != GRN_SUCCESS) { + g_print("failed to initialize Groonga: <%d>: %s\n", + rc, grn_get_global_error_message()); + return EXIT_FAILURE; + } + bench_init(&argc, &argv); + + data.context = g_new(grn_ctx, 1); + data.base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL); + data.name = "table"; + data.name_size = strlen(data.name); + data.path = g_build_filename(data.base_dir, "table", NULL); + data.flags = DEFAULT_FLAGS; + data.key_type = NULL; + data.value_size = DEFAULT_VALUE_SIZE; + data.encoding = GRN_ENC_DEFAULT; + + reporter = bench_reporter_new(); + bench_reporter_register(reporter, "normal (persistent)", n, + bench_setup, bench_normal, bench_teardown, &data); + bench_reporter_register(reporter, "factory (persistent)", n, + bench_setup, bench_factory, bench_teardown, &data); + bench_reporter_register(reporter, "normal (temporary)", n, + bench_setup, bench_normal_temporary, bench_teardown, + &data); + bench_reporter_register(reporter, "factory (temporary)", n, + bench_setup, bench_factory_temporary, bench_teardown, + &data); + bench_reporter_run(reporter); + g_object_unref(reporter); + + bench_utils_remove_path_recursive_force(data.base_dir); + + g_free(data.path); + g_free(data.base_dir); + g_free(data.context); + + bench_quit(); + grn_fin(); + + return EXIT_SUCCESS; +} diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/fixtures/Makefile.am new file mode 100644 index 00000000..3b7136f7 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = \ + geo-select diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/13_2010.CSV.xz b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/13_2010.CSV.xz Binary files differnew file mode 100644 index 00000000..3cef5268 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/13_2010.CSV.xz diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/Makefile.am new file mode 100644 index 00000000..3aa25594 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/Makefile.am @@ -0,0 +1,4 @@ +EXTRA_DIST = \ + README.txt \ + 13_2010.CSV.xz \ + format_2010.html diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/README.txt b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/README.txt new file mode 100644 index 00000000..c4a0620a --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/README.txt @@ -0,0 +1,6 @@ +位置情報検索ベンチマーク用テストデータについて +-------------------------------------------- + +13_2010.CSV.xzは国土交通相の `位置参照情報ダウンロードサービス <http://nlftp.mlit.go.jp/isj/>`_ からダウンロードした2010年版の東京都の「大字・町丁目位置参照情報 国土交通省」です。xz圧縮しているだけでデータの編集・加工はしていません。CSVのフォーマットについてはformat_2010.htmlを参照してください。こちらもダウンロードサービスに含まれているものを編集・加工していません。 + +`位置参照情報ダウンロードサービス利用約款 <http://nlftp.mlit.go.jp/isj/agreement.html>`_ に従い、上記のように出典を明記して利用しています。 diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/format_2010.html b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/format_2010.html new file mode 100644 index 00000000..5c2396c4 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/format_2010.html @@ -0,0 +1,111 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> +<head> +<title>X惌xʒuQƏ (2010)</title> +<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> +</head> + + <body> + <h3 align="center">X惌xʒuQƏ (2010N) f[^`</h3> + <table width="90%" align="center"> + <tr> + <td> + t@C`CSV(Camma Separated Values)łB<br/> + R[h́AShift-JISłB<br/> + </td> + </tr> + <tr> + <td> + <table width="100%" align="center" border="1"> + <tr> + <th></th> + <th>l</th> + <th></th> + </tr> + <tr> + <td>s{</td> + <td><br/></td> + <td>"s"</td> + </tr> + <tr> + <td>s撬</td> + <td>S͌SAߎwss̋於܂ށB</td> + <td>"c"</td> + </tr> + <tr> + <td>厚E</td> + <td>ڂ̐͊</td> + <td>"֓"</td> + </tr> + <tr> + <td>X敄En</td> + <td>ƂĔpiꕔj</td> + <td>"1"</td> + </tr> + <tr> + <td>Wnԍ</td> + <td>ʒpWn̍Wnԍi1`19Fpj</td> + <td>9</td> + </tr> + <tr> + <td>wW</td> + <td> + ʒpWn̍Wn_̂<br/> + iPʁF[gAkvXlA_ȉ1ʂ܂Łj + </td> + <td>-35925.9</td> + </tr> + <tr> + <td>xW</td> + <td> + ʒpWn̍Wn_̂<br/> + iPʁF[gAvXlA_ȉ1ʂ܂Łj + </td> + <td>-7446.2</td> + </tr> + <tr> + <td>ܓx</td> + <td>\ioܓxiPʁFxA_ȉ6ʂ܂Łj</td> + <td>35.676155</td> + </tr> + <tr> + <td>ox</td> + <td>\ioܓxiPʁFxA_ȉ6ʂ܂Łj</td> + <td>139.751075</td> + </tr> + <tr> + <td>Z\tO</td> + <td>1FZ\{A0FZ\{</td> + <td>1</td> + </tr> + <tr> + <td>\tO</td> + <td> + 1̊X敄̑\_ɑΉtꍇȂǂɁÂ1ɕXIɑ\tO𗧂ĂĂ܂B<br/> + 1F\A0F\Ȃ + <td>1</td> + </tr> + <tr> + <td>XVOtO</td> + <td>2007Nx2008Nxf[^Ɋ܂܂tO𗧂ĂĂ܂B<br/> + 1FVK쐬A2F̕ύXA3F폜A0FύXȂ</td> + <td>0</td> + </tr> + <tr> + <td>XV㗚tO</td> + <td>2009Nxȍ~̃f[^Ɋ܂܂tO𗧂ĂĂ܂B<br/> + 1FVK쐬A2F̕ύXA3F폜A0FύXȂ</td> + <td>0</td> + </tr> + </table> + </td> + </tr> + <tr> + <td align="right"> + 23N0418쐬 + </td> + </tr> + </table> +</body> + +</html> diff --git a/storage/mroonga/vendor/groonga/benchmark/geo-distance-summary.rb b/storage/mroonga/vendor/groonga/benchmark/geo-distance-summary.rb new file mode 100755 index 00000000..6559cb60 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/geo-distance-summary.rb @@ -0,0 +1,140 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +require 'fileutils' +require 'optparse' + +class BenchmarkSummary + attr_accessor :options + + def initialize(options) + @options = options + @options[:count] ||= 10 + end + + def calc_total(data) + total = {} + @options[:count].times do |i| + data[i + 1].each do |key, value| + if total[key] + total[key] = total[key] + value + else + total[key] = value + end + end + end + total + end + + def print_average(data) + total = calc_total(data) + text = "|項目|" + @options[:count].times do |i| + text << "#{i + 1}|" + text << "平均|\n" if i == @options[:count] - 1 + end + total.each do |key, value| + line = [key] + @options[:count].times do |i| + data[i + 1].each do |data_key, data_value| + if key == data_key + line << data_value + end + end + end + line << [value / @options[:count].to_f] + text << sprintf("|%s|\n", line.join("|")) + end + puts text + end + + def print_performance(before, after) + before_total = calc_total(before) + after_total = calc_total(after) + ratio = {} + before_total.each do |key, value| + ratio[key] = after_total[key] / value + end + text = "|項目|変更前|変更後|比率|備考|\n" + ratio.each do |key, value| + text << sprintf("|%s|%f|%f|%f||\n", + key, + before_total[key] / @options[:count].to_f, + after_total[key] / @options[:count].to_f, + ratio[key]) + end + puts text + end + + def parse_log(logs) + parse_result = {} + logs.each do |index, log| + File.open(log, "r") do |file| + data = file.read + entry = {} + data.split("\n").each do |line| + if line =~ /\s*(.+?):\s+\((.+)\)/ + entry[$1] = $2.to_f + end + end + parse_result[index] = entry + end + end + parse_result + end +end + +=begin + +Usage: geo-distance-summary.rb \ +-b run-bench-geo-distance-orig-N1000 \ +-a run-bench-geo-distance-work-N1000 + +NOTE: expected that there are run-bench-geo-distance-orig-N1000-1.log \ +... \ +run-bench-geo-distance-orig-N1000-[N].log. + +=end + +if __FILE__ == $0 + + options = {} + parser = OptionParser.new + parser.on("-b", "--before PREFIX", + "log file name must be PREFIX-[N].log") do |prefix| + options[:before] = prefix + end + parser.on("-a", "--after PREFIX", + "log file name must be PREFIX-[N].log") do |prefix| + options[:after] = prefix + end + parser.on("-n", "data count") do |count| + options[:count] = count + end + + parser.parse!(ARGV) + + if not options.has_key?(:before) or not options.has_key?(:after) + puts(parser.to_s) + exit + end + + bench_before_log = {} + bench_after_log = {} + Dir.glob("#{options[:before]}*.log") do |log| + log =~ /(.+)-(\d+)\.log$/ + bench_before_log[$2.to_i] = log + end + Dir.glob("#{options[:after]}*.log") do |log| + log =~ /(.+)-(\d+)\.log$/ + bench_after_log[$2.to_i] = log + end + + bench = BenchmarkSummary.new(options) + bench_before = bench.parse_log(bench_before_log) + bench_after = bench.parse_log(bench_after_log) + + bench.print_average(bench_before) + bench.print_average(bench_after) + bench.print_performance(bench_before, bench_after) +end diff --git a/storage/mroonga/vendor/groonga/benchmark/geo-select-generate-grn.rb b/storage/mroonga/vendor/groonga/benchmark/geo-select-generate-grn.rb new file mode 100755 index 00000000..dc90f7e6 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/geo-select-generate-grn.rb @@ -0,0 +1,53 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +if ARGV.size != 2 + puts "Usage: #{$0} SOURCE_CSV OUTPUT_GRN" + puts " e.g.: #{$0} fixtures/geo-select/13_2010.CSV fixtures/geo-select/load.grn" + exit(false) +end + +csv, grn = ARGV + +require "fileutils" +require "csv" + +FileUtils.mkdir_p(File.dirname(grn)) +File.open(grn, "w") do |output| + output.print(<<-EOH.strip) +table_create Addresses TABLE_HASH_KEY ShortText +column_create Addresses location COLUMN_SCALAR WGS84GeoPoint + +table_create Locations TABLE_PAT_KEY WGS84GeoPoint +column_create Locations address COLUMN_INDEX Addresses location + +load --table Addresses +[ +["_key", "location"] +EOH + + headers = nil + csv_foreach_args = [csv] + csv_foreach_args << {:encoding => "UTF-8"} if defined?(Encoding) + CSV.foreach(*csv_foreach_args) do |row| + if headers.nil? + headers = row + else + record = {} + headers.each_with_index do |header, i| + record[header] = row[i] + end + central_value_p = record["代表フラグ"] == "1" + next unless central_value_p + name = + record["都道府県名"] + record["市区町村名"] + + record["大字・町丁目"] + record["街区符号・地番"] + location = "%sx%s" % [record["緯度"], record["経度"]] + output.print(",\n[\"#{name}\", \"#{location}\"]") + end + end + output.print(<<-EOF) + +] +EOF +end diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am new file mode 100644 index 00000000..2031b9aa --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am @@ -0,0 +1,24 @@ +if WITH_BENCHMARK +noinst_LTLIBRARIES = \ + libbenchmark.la +endif + +AM_CPPFLAGS = \ + -I$(srcdir) + +AM_CFLAGS = \ + $(GLIB_CFLAGS) + +CFLAGS += \ + $(NO_BAD_FUNCTION_CAST_CFLAGS) + +LIBS = \ + $(GLIB_LIBS) + +libbenchmark_la_SOURCES = \ + benchmark.c \ + benchmark.h \ + bench-reporter.c \ + bench-reporter.h \ + bench-utils.c \ + bench-utils.h diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.c b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.c new file mode 100644 index 00000000..cb435976 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.c @@ -0,0 +1,315 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#include <string.h> + +#include "bench-reporter.h" + +typedef struct _BenchItem BenchItem; +struct _BenchItem +{ + gchar *label; + gint n; + BenchSetupFunc bench_setup; + BenchFunc bench; + BenchTeardownFunc bench_teardown; + gpointer data; +}; + +static BenchItem * +bench_item_new(const gchar *label, gint n, + BenchSetupFunc bench_setup, + BenchFunc bench, + BenchTeardownFunc bench_teardown, + gpointer data) +{ + BenchItem *item; + + item = g_slice_new(BenchItem); + + item->label = g_strdup(label); + item->n = n; + item->bench_setup = bench_setup; + item->bench = bench; + item->bench_teardown = bench_teardown; + item->data = data; + + return item; +} + +static void +bench_item_free(BenchItem *item) +{ + if (item->label) + g_free(item->label); + + g_slice_free(BenchItem, item); +} + +#define BENCH_REPORTER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + BENCH_TYPE_REPORTER, \ + BenchReporterPrivate)) + +typedef struct _BenchReporterPrivate BenchReporterPrivate; +struct _BenchReporterPrivate +{ + GList *items; +}; + +G_DEFINE_TYPE(BenchReporter, bench_reporter, G_TYPE_OBJECT) + +static void dispose (GObject *object); + +static void +bench_reporter_class_init(BenchReporterClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = dispose; + + g_type_class_add_private(gobject_class, sizeof(BenchReporterPrivate)); +} + +static void +bench_reporter_init(BenchReporter *reporter) +{ + BenchReporterPrivate *priv; + + priv = BENCH_REPORTER_GET_PRIVATE(reporter); + + priv->items = NULL; +} + +static void +dispose(GObject *object) +{ + BenchReporterPrivate *priv; + + priv = BENCH_REPORTER_GET_PRIVATE(object); + + if (priv->items) { + g_list_foreach(priv->items, (GFunc)bench_item_free, NULL); + g_list_free(priv->items); + priv->items = NULL; + } + + G_OBJECT_CLASS(bench_reporter_parent_class)->dispose(object); +} + +BenchReporter * +bench_reporter_new(void) +{ + return g_object_new(BENCH_TYPE_REPORTER, NULL); +} + +void +bench_reporter_register(BenchReporter *reporter, + const gchar *label, gint n, + BenchSetupFunc bench_setup, + BenchFunc bench, + BenchTeardownFunc bench_teardown, + gpointer data) +{ + BenchReporterPrivate *priv; + + priv = BENCH_REPORTER_GET_PRIVATE(reporter); + + priv->items = g_list_append(priv->items, bench_item_new(label, n, + bench_setup, + bench, + bench_teardown, + data)); +} + +#define INDENT " " + +static void +print_header(BenchReporterPrivate *priv, gint max_label_length) +{ + gint n_spaces; + + g_print(INDENT); + for (n_spaces = max_label_length + strlen(": "); + n_spaces > 0; + n_spaces--) { + g_print(" "); + } + g_print("(total) "); + g_print("(average) "); + g_print("(median)\n"); +} + +static void +print_label(BenchReporterPrivate *priv, BenchItem *item, gint max_label_length) +{ + gint n_left_spaces; + + g_print(INDENT); + if (item->label) { + n_left_spaces = max_label_length - strlen(item->label); + } else { + n_left_spaces = max_label_length; + } + for (; n_left_spaces > 0; n_left_spaces--) { + g_print(" "); + } + if (item->label) + g_print("%s", item->label); + g_print(": "); +} + +static void +report_elapsed_time(gdouble elapsed_time) +{ + gdouble one_second = 1.0; + gdouble one_millisecond = one_second / 1000.0; + gdouble one_microsecond = one_millisecond / 1000.0; + + if (elapsed_time < one_microsecond) { + g_print("(%.8fms)", elapsed_time * 1000.0); + } else if (elapsed_time < one_millisecond) { + g_print("(%.4fms)", elapsed_time * 1000.0); + } else { + g_print("(%.4fs) ", elapsed_time); + } +} + +static gdouble +compute_total_elapsed_time(GArray *elapsed_times) +{ + guint i; + gdouble total = 0.0; + + for (i = 0; i< elapsed_times->len; i++) { + gdouble elapsed_time = g_array_index(elapsed_times, gdouble, i); + total += elapsed_time; + } + + return total; +} + +static void +report_elapsed_time_total(GArray *elapsed_times) +{ + report_elapsed_time(compute_total_elapsed_time(elapsed_times)); +} + +static void +report_elapsed_time_average(GArray *elapsed_times) +{ + gdouble total; + gdouble average; + + total = compute_total_elapsed_time(elapsed_times); + average = total / elapsed_times->len; + report_elapsed_time(average); +} + +static gint +compare_elapsed_time(gconstpointer a, gconstpointer b) +{ + const gdouble *elapsed_time1 = a; + const gdouble *elapsed_time2 = b; + + if (*elapsed_time1 > *elapsed_time2) { + return 1; + } else if (*elapsed_time1 < *elapsed_time2) { + return -1; + } else { + return 0; + } +} + +static void +report_elapsed_time_median(GArray *elapsed_times) +{ + gdouble median; + + g_array_sort(elapsed_times, compare_elapsed_time); + median = g_array_index(elapsed_times, gdouble, elapsed_times->len / 2); + report_elapsed_time(median); +} + +static void +report_elapsed_time_statistics(GArray *elapsed_times) +{ + report_elapsed_time_total(elapsed_times); + g_print(" "); + report_elapsed_time_average(elapsed_times); + g_print(" "); + report_elapsed_time_median(elapsed_times); + g_print("\n"); +} + +static void +run_item(BenchReporterPrivate *priv, BenchItem *item, gint max_label_length) +{ + GTimer *timer; + GArray *elapsed_times; + gint i; + + print_label(priv, item, max_label_length); + + elapsed_times = g_array_new(FALSE, FALSE, sizeof(gdouble)); + + timer = g_timer_new(); + for (i = 0; i < item->n; i++) { + gdouble elapsed_time; + if (item->bench_setup) + item->bench_setup(item->data); + g_timer_start(timer); + item->bench(item->data); + g_timer_stop(timer); + elapsed_time = g_timer_elapsed(timer, NULL); + g_array_append_val(elapsed_times, elapsed_time); + if (item->bench_teardown) + item->bench_teardown(item->data); + } + g_timer_destroy(timer); + + report_elapsed_time_statistics(elapsed_times); + + g_array_free(elapsed_times, TRUE); + +} + +void +bench_reporter_run(BenchReporter *reporter) +{ + BenchReporterPrivate *priv; + GList *node; + gint max_label_length = 0; + + priv = BENCH_REPORTER_GET_PRIVATE(reporter); + for (node = priv->items; node; node = g_list_next(node)) { + BenchItem *item = node->data; + + if (item->label) + max_label_length = MAX(max_label_length, strlen(item->label)); + } + + print_header(priv, max_label_length); + for (node = priv->items; node; node = g_list_next(node)) { + BenchItem *item = node->data; + + run_item(priv, item, max_label_length); + } +} diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.h b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.h new file mode 100644 index 00000000..d2c408c7 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.h @@ -0,0 +1,64 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#ifndef __BENCH_REPORTER_H__ +#define __BENCH_REPORTER_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define BENCH_TYPE_REPORTER (bench_reporter_get_type()) +#define BENCH_REPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), BENCH_TYPE_REPORTER, BenchReporter)) +#define BENCH_REPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), BENCH_TYPE_REPORTER, BenchReporterClass)) +#define BENCH_IS_REPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), BENCH_TYPE_REPORTER)) +#define BENCH_IS_REPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), BENCH_TYPE_REPORTER)) +#define BENCH_REPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), BENCH_TYPE_REPORTER, BenchReporterClass)) + +typedef struct _BenchReporter BenchReporter; +typedef struct _BenchReporterClass BenchReporterClass; + +typedef void (*BenchSetupFunc) (gpointer user_data); +typedef void (*BenchFunc) (gpointer user_data); +typedef void (*BenchTeardownFunc) (gpointer user_data); + +struct _BenchReporter +{ + GObject object; +}; + +struct _BenchReporterClass +{ + GObjectClass parent_class; +}; + +GType bench_reporter_get_type (void) G_GNUC_CONST; + +BenchReporter *bench_reporter_new (void); +void bench_reporter_register (BenchReporter *reporter, + const gchar *label, + gint n, + BenchSetupFunc bench_setup, + BenchFunc bench, + BenchTeardownFunc bench_teardown, + gpointer data); +void bench_reporter_run (BenchReporter *reporter); + +#endif /* __BENCH_REPORTER_H__ */ + + diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.c b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.c new file mode 100644 index 00000000..ef731b51 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.c @@ -0,0 +1,83 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#include <errno.h> +#include <glib/gstdio.h> + +#include "bench-utils.h" + +gboolean +bench_utils_remove_path(const gchar *path, GError **error) +{ + if (!g_file_test(path, G_FILE_TEST_EXISTS)) { + g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT, + "path doesn't exist: %s", path); + return FALSE; + } + + if (g_file_test(path, G_FILE_TEST_IS_DIR)) { + if (g_rmdir(path) == -1) { + g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), + "can't remove directory: %s", path); + return FALSE; + } + } else { + if (g_unlink(path) == -1) { + g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), + "can't remove path: %s", path); + return FALSE; + } + } + + return TRUE; +} + +gboolean +bench_utils_remove_path_recursive(const gchar *path, GError **error) +{ + if (g_file_test(path, G_FILE_TEST_IS_DIR)) { + GDir *dir; + const gchar *name; + + dir = g_dir_open(path, 0, error); + if (!dir) + return FALSE; + + while ((name = g_dir_read_name(dir))) { + const gchar *full_path; + + full_path = g_build_filename(path, name, NULL); + if (!bench_utils_remove_path_recursive(full_path, error)) + return FALSE; + } + + g_dir_close(dir); + + return bench_utils_remove_path(path, error); + } else { + return bench_utils_remove_path(path, error); + } + + return TRUE; +} + +void +bench_utils_remove_path_recursive_force(const gchar *path) +{ + bench_utils_remove_path_recursive(path, NULL); +} diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.h b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.h new file mode 100644 index 00000000..b48e6f34 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.h @@ -0,0 +1,34 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#ifndef __BENCH_UTILS_H__ +#define __BENCH_UTILS_H__ + +#include <glib.h> + +G_BEGIN_DECLS + +gboolean bench_utils_remove_path (const gchar *path, + GError **error); +gboolean bench_utils_remove_path_recursive (const gchar *path, + GError **error); +void bench_utils_remove_path_recursive_force (const gchar *path); + +G_END_DECLS + +#endif /* __BENCH_UTILS_H__ */ diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.c b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.c new file mode 100644 index 00000000..679889a4 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.c @@ -0,0 +1,35 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2008-2013 Kouhei Sutou <kou@clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#include "benchmark.h" + +void +bench_init(gint *argc, gchar ***argv) +{ +#if !GLIB_CHECK_VERSION(2, 36, 0) + if (!g_thread_supported()) + g_thread_init(NULL); + + g_type_init(); +#endif +} + +void +bench_quit(void) +{ +} diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.h b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.h new file mode 100644 index 00000000..7d34b8f2 --- /dev/null +++ b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.h @@ -0,0 +1,32 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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-1335 USA +*/ + +#ifndef __BENCHMARK_H__ +#define __BENCHMARK_H__ + +#include "bench-reporter.h" +#include "bench-utils.h" + +G_BEGIN_DECLS + +void bench_init(gint *argc, gchar ***argv); +void bench_quit(void); + +G_END_DECLS + +#endif |