diff options
Diffstat (limited to 'test/bench.c')
| -rw-r--r-- | test/bench.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/test/bench.c b/test/bench.c new file mode 100644 index 0000000..83330aa --- /dev/null +++ b/test/bench.c @@ -0,0 +1,204 @@ +#define TS_IMPLEMENTATION +#include "ts.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#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; +} |