Skip to content

Commit

Permalink
add a benchmark for geo distance.
Browse files Browse the repository at this point in the history
  • Loading branch information
kou authored and daijiro committed Feb 4, 2010
1 parent cbb1f8a commit ac9ee44
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 1 deletion.
1 change: 1 addition & 0 deletions test/benchmark/.gitignore
@@ -1 +1,2 @@
/bench-geo-distance
/bench-table-factory
4 changes: 3 additions & 1 deletion test/benchmark/Makefile.am
Expand Up @@ -3,7 +3,8 @@ SUBDIRS = \

if WITH_BENCHMARK
noinst_PROGRAMS = \
bench-table-factory
bench-table-factory \
bench-geo-distance
endif

INCLUDES = \
Expand All @@ -22,6 +23,7 @@ LIBS = \
$(GLIB_LIBS)

bench_table_factory_SOURCES = bench-table-factory.c
bench_geo_distance_SOURCES = bench-geo-distance.c

benchmark:
@for benchmark in $(noinst_PROGRAMS); do \
Expand Down
260 changes: 260 additions & 0 deletions test/benchmark/bench-geo-distance.c
@@ -0,0 +1,260 @@
/* -*- c-basic-offset: 2; coding: utf-8 -*- */
/*
Copyright (C) 2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <db.h>
#include <groonga.h>

#include "lib/benchmark.h"

#define GET(context, name) (grn_ctx_get(context, name, strlen(name)))

grn_rc grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller);
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_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)
{
BenchmarkData data;
BenchReporter *reporter;
gint n = 1000;

grn_init();
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("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 0;
}

0 comments on commit ac9ee44

Please sign in to comment.