From fa20e159b527ec0bdd4772d3d9f5d8a7a981a6fb Mon Sep 17 00:00:00 2001
From: Stepan Neretin <sncfmgg@gmail.com>
Date: Tue, 11 Jun 2024 12:07:01 +0700
Subject: [PATCH v42 09/12] Introduce benchmarking function for int16 array
 sorting

This commit adds a benchmarking function, bench_int16_sort, to compare
the performance of two sorting methods for int16 arrays: the standard
qsort function and the optimized sort_int_16_arr function. The benchmark
generates two arrays of random int16 values, sorts each array using
both methods, and measures the time taken for each sorting operation.
Additionally, it calculates the percentage difference in execution time
between the two methods.

  Details:
- Added a benchmarking function to compare sorting methods for int16 arrays.
- Generates random int16 arrays for benchmarking.
- Measures execution time for sorting using both qsort and optimized sort_int_16_arr.
- Calculates percentage difference in execution time between methods.
---
 contrib/bench_sort_improvements/bench.c       | 55 +++++++++++++++++++
 .../bench_sort_improvements--1.0.sql          |  2 +
 2 files changed, 57 insertions(+)

diff --git a/contrib/bench_sort_improvements/bench.c b/contrib/bench_sort_improvements/bench.c
index 77d5c7fa37..c0d4ec86e1 100644
--- a/contrib/bench_sort_improvements/bench.c
+++ b/contrib/bench_sort_improvements/bench.c
@@ -9,10 +9,12 @@
 PG_MODULE_MAGIC;
 
 Datum bench_int_sort(PG_FUNCTION_ARGS);
+Datum bench_int16_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);
 
 Datum
 bench_oid_sort(PG_FUNCTION_ARGS)
@@ -98,6 +100,59 @@ bench_int_sort(PG_FUNCTION_ARGS)
     PG_RETURN_TEXT_P(cstring_to_text(result_message));
 }
 
+/*
+stupid copy for tests
+*/
+static int
+compare_int16(const void *a, const void *b)
+{
+	int			av = *(const int16 *) a;
+	int			bv = *(const int16 *) b;
+
+	/* this can't overflow if int is wider than int16 */
+	return (av - bv);
+}
+
+Datum
+bench_int16_sort(PG_FUNCTION_ARGS)
+{
+    int32 arr_size = PG_GETARG_INT32(0);
+    int16 *arr_first = (int16 *)palloc(arr_size * sizeof(int16));
+    int16 *arr_second = (int16 *)palloc(arr_size * sizeof(int16));
+    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] = (int16)rand();
+        arr_second[i] = (int16)rand();
+    }
+
+    // Timing the first sort function
+    clock_gettime(CLOCK_MONOTONIC, &start);
+    qsort(arr_first, arr_size, sizeof(int16), compare_int16);
+    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_int_16_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 97b75d368d..bff8a6ab59 100644
--- a/contrib/bench_sort_improvements/bench_sort_improvements--1.0.sql
+++ b/contrib/bench_sort_improvements/bench_sort_improvements--1.0.sql
@@ -1,3 +1,5 @@
 create function bench_oid_sort(integer) returns text AS 'MODULE_PATHNAME', 'bench_oid_sort' LANGUAGE C;
 
 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;
-- 
2.34.1

