#define TS_IMPLEMENTATION #include "ts.h" #include #include #include #include #define BENCH_N 10000 #define BENCH_ITER 100 typedef struct { uint_t k; fp_t std_mult; } bb_params_t; typedef struct { fp_t fast_k; fp_t slow_k; fp_t signal_k; } macd_params_t; typedef struct { fp_t Q; fp_t R; } kalman_params_t; static fp_t bench_input[BENCH_N]; static fp_t bench_output[BENCH_N]; static fp_t bench_ohlc[4][BENCH_N]; static fp_t bench_output_multi[4][BENCH_N]; static double elapsed_ms(struct timespec *start, struct timespec *end) { return (end->tv_sec - start->tv_sec) * 1000.0 + (end->tv_nsec - start->tv_nsec) / 1000000.0; } int main(void) { ts_fill(bench_input, BENCH_N, 0, BENCH_N); for (uint_t c = 0; c < 4; c++) { ts_fill(bench_ohlc[c], BENCH_N, 100 + c, 200 + c); } printf("Benchmark: n=%d, iterations=%d\n", BENCH_N, BENCH_ITER); printf("--------------------------------------------------\n"); struct timespec start, end; /* ts_average */ { uint_t k = 14; fp_t * const y[1] = { bench_output }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_average(y, 1, x, 1, BENCH_N, (ts_constant_t *)&k); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_average", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_rsi */ { uint_t k = 14; fp_t * const y[1] = { bench_output }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_rsi(y, 1, x, 1, BENCH_N, (ts_constant_t *)&k); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_rsi", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_deviation_standard */ { uint_t k = 14; fp_t * const y[1] = { bench_output }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_deviation_standard(y, 1, x, 1, BENCH_N, (ts_constant_t *)&k); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_deviation_standard", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_average_exponential */ { uint_t k = 14; fp_t * const y[1] = { bench_output }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_average_exponential(y, 1, x, 1, BENCH_N, (ts_constant_t *)&k); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_average_exponential", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_bollinger_bands */ { bb_params_t c = { .k = 20, .std_mult = 2.0 }; fp_t * const y[3] = { bench_output_multi[0], bench_output_multi[1], bench_output_multi[2] }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_bollinger_bands(y, 3, x, 1, BENCH_N, (ts_constant_t *)&c); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_bollinger_bands", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_macd */ { macd_params_t c = { .fast_k = 12, .slow_k = 26, .signal_k = 9 }; fp_t * const y[3] = { bench_output_multi[0], bench_output_multi[1], bench_output_multi[2] }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_macd(y, 3, x, 1, BENCH_N, (ts_constant_t *)&c); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_macd", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_atr */ { uint_t k = 14; fp_t * const y[1] = { bench_output }; fp_t const * const x[4] = { bench_ohlc[0], bench_ohlc[1], bench_ohlc[2], bench_ohlc[3] }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_atr(y, 1, x, 4, BENCH_N, (ts_constant_t *)&k); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_atr", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_adx */ { uint_t k = 14; fp_t * const y[4] = { bench_output_multi[0], bench_output_multi[1], bench_output_multi[2], bench_output_multi[3] }; fp_t const * const x[4] = { bench_ohlc[0], bench_ohlc[1], bench_ohlc[2], bench_ohlc[3] }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_adx(y, 4, x, 4, BENCH_N, (ts_constant_t *)&k); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_adx", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_kalman_filter */ { kalman_params_t c = { .Q = 0.01, .R = 0.05 }; fp_t * const y[1] = { bench_output }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_kalman_filter(y, 1, x, 1, BENCH_N, (ts_constant_t *)&c); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_kalman_filter", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_absolute_value */ { fp_t * const y[1] = { bench_output }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_absolute_value(y, 1, x, 1, BENCH_N, NULL); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_absolute_value", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_sine */ { fp_t * const y[1] = { bench_output }; fp_t const * const x[1] = { bench_input }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_sine(y, 1, x, 1, BENCH_N, NULL); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_sine", ms, ms * 1000000.0 / BENCH_ITER); } /* ts_addition */ { fp_t * const y[1] = { bench_output }; fp_t const * const x[2] = { bench_input, bench_ohlc[0] }; clock_gettime(CLOCK_MONOTONIC, &start); for (uint_t i = 0; i < BENCH_ITER; i++) { (void)ts_addition(y, 1, x, 2, BENCH_N, NULL); } clock_gettime(CLOCK_MONOTONIC, &end); double ms = elapsed_ms(&start, &end); printf("%-40s %8.2f ms (%.0f ns/call)\n", "ts_addition", ms, ms * 1000000.0 / BENCH_ITER); } return 0; }