From 4341f7ff48004bef2fe9707f1a03236d0bd7c4e7 Mon Sep 17 00:00:00 2001
From: Stepan Neretin <sncfmgg@gmail.com>
Date: Tue, 11 Jun 2024 12:42:03 +0700
Subject: [PATCH v42 12/12] Add benchmark comparing float8 sorting methods

Introduce `bench_float8_sort` to compare qsort with `sort_float8_arr`. It generates random float8 arrays, times sorting, and calculates performance difference.
---
 contrib/bench_sort_improvements/bench.c       | 70 +++++++++++++++++++
 .../bench_sort_improvements--1.0.sql          |  2 +
 2 files changed, 72 insertions(+)

diff --git a/contrib/bench_sort_improvements/bench.c b/contrib/bench_sort_improvements/bench.c
index c0d4ec86e1..a4088783c6 100644
--- a/contrib/bench_sort_improvements/bench.c
+++ b/contrib/bench_sort_improvements/bench.c
@@ -10,11 +10,13 @@ PG_MODULE_MAGIC;
 
 Datum bench_int_sort(PG_FUNCTION_ARGS);
 Datum bench_int16_sort(PG_FUNCTION_ARGS);
+Datum bench_float8_sort(PG_FUNCTION_ARGS);
 Datum bench_oid_sort(PG_FUNCTION_ARGS);
 
 PG_FUNCTION_INFO_V1(bench_oid_sort);
 PG_FUNCTION_INFO_V1(bench_int_sort);
 PG_FUNCTION_INFO_V1(bench_int16_sort);
+PG_FUNCTION_INFO_V1(bench_float8_sort);
 
 Datum
 bench_oid_sort(PG_FUNCTION_ARGS)
@@ -153,6 +155,74 @@ bench_int16_sort(PG_FUNCTION_ARGS)
     PG_RETURN_TEXT_P(cstring_to_text(result_message));
 }
 
+double inline rand_double() {
+    return (double)rand() / RAND_MAX; 
+}
+
+/*
+stupid copy for tests
+*/
+static int
+compareDoubles(const void *a, const void *b)
+{
+	float8		x = *(float8 *) a;
+	float8		y = *(float8 *) b;
+
+	if (x == y)
+		return 0;
+	return (x > y) ? 1 : -1;
+}
+
+/*
+stupid copy for tests
+*/
+#define ST_SORT sort_float8_arr
+#define ST_ELEMENT_TYPE float8
+#define ST_COMPARE(a, b) compareDoubles(a, b)
+#define ST_SCOPE static
+#define ST_DEFINE
+#include <lib/sort_template.h>
+
+Datum
+bench_float8_sort(PG_FUNCTION_ARGS)
+{
+    int32 arr_size = PG_GETARG_INT32(0);
+    float8 *arr_first = (float8 *)palloc(arr_size * sizeof(float8));
+    float8 *arr_second = (float8 *)palloc(arr_size * sizeof(float8));
+    struct timespec start, end;
+    long time_spent_first;
+    long time_spent_second;
+    double percentage_difference = 0.0;
+    char *result_message;
+
+    for (int i = 0; i < arr_size; i++)
+    {
+        arr_first[i] = rand_double();
+        arr_second[i] = rand_double();
+    }
+
+    // Timing the first sort function
+    clock_gettime(CLOCK_MONOTONIC, &start);
+    qsort(arr_first, arr_size, sizeof(float8), compareDoubles);
+    clock_gettime(CLOCK_MONOTONIC, &end);
+    time_spent_first = (end.tv_sec - start.tv_sec) * 1000000000L + (end.tv_nsec - start.tv_nsec);
+
+    // Timing the second sort function
+    clock_gettime(CLOCK_MONOTONIC, &start);
+    sort_float8_arr(arr_second, arr_size);
+    clock_gettime(CLOCK_MONOTONIC, &end);
+    time_spent_second = (end.tv_sec - start.tv_sec) * 1000000000L + (end.tv_nsec - start.tv_nsec);
+
+    percentage_difference = ((double)(time_spent_first - time_spent_second) / time_spent_first) * 100.0;
+
+    pfree(arr_first);
+    pfree(arr_second);
+    
+    result_message = psprintf("Time taken by usual sort: %ld ns, Time taken by optimized sort: %ld ns, Percentage difference: %.2f%%", 
+                              time_spent_first, time_spent_second, percentage_difference);
+    PG_RETURN_TEXT_P(cstring_to_text(result_message));
+}
+
 void
 _PG_init()
 {
diff --git a/contrib/bench_sort_improvements/bench_sort_improvements--1.0.sql b/contrib/bench_sort_improvements/bench_sort_improvements--1.0.sql
index bff8a6ab59..5c51a5ef81 100644
--- a/contrib/bench_sort_improvements/bench_sort_improvements--1.0.sql
+++ b/contrib/bench_sort_improvements/bench_sort_improvements--1.0.sql
@@ -3,3 +3,5 @@ create function bench_oid_sort(integer) returns text AS 'MODULE_PATHNAME', 'benc
 create function bench_int_sort(integer) returns text AS 'MODULE_PATHNAME', 'bench_int_sort' LANGUAGE C;
 
 create function bench_int16_sort(integer) returns text AS 'MODULE_PATHNAME', 'bench_int16_sort' LANGUAGE C;
+
+create function bench_float8_sort(integer) returns text AS 'MODULE_PATHNAME', 'bench_float8_sort' LANGUAGE C;
-- 
2.34.1

