mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-26 16:38:11 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			506 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* -*- 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;
 | |
| }
 | 
