#ifndef TIME_IT_H #define TIME_IT_H #include #include #define ARRAY_OF double #include "array.h" /* * time_it - executes the provided code and returns a * following argument (a1, a2, ..., an) * resulting in (fun(a1)), (fun(a2)), ..., (fun(an)) * * @code: the code to time; It can be a simple function call or * a full block code * @...: the optional argument number that * * @return: the elapsed execution time in seconds * Note: fun can be either a macro, a function or a cast * in parenthesis (e.g. for_each((char), 67, 10)) */ #define time_it(code, ...) TIME_IT_NOT_EXPOSED__GENERIC_IMPLEMENTATION(, code, __VA_ARGS__) /* * for_each - apply a function-like object (fun) to each * following argument (a1, a2, ..., an) * resulting in (fun(a1)), (fun(a2)), ..., (fun(an)) * * @fun: the function-like object to apply * @...: the list of agurments on which to apply * * Note: fun can be either a macro, a function or a cast * in parenthesis (e.g. for_each((char), 67, 10)) */ #define time_it_repeat(code, ...) TIME_IT_NOT_EXPOSED__GENERIC_IMPLEMENTATION(REPEAT, code, __VA_ARGS__) #define TIME_IT_NOT_EXPOSED__GENERIC_IMPLEMENTATION(type, code, ...) __extension__({ \ struct time_it_params { TIME_IT_NOT_EXPOSED__IF_REPEAT(type, size_t repeat;) size_t number;} time_it_params = (struct time_it_params){ TIME_IT_NOT_EXPOSED__IF_REPEAT(type, .repeat = 1, _) .number = 1}; \ __VA_OPT__(time_it_params TIME_IT_NOT_EXPOSED__FIRST_ARG(__VA_ARGS__);) \ __VA_OPT__(TIME_IT_NOT_EXPOSED__MAYBE_SECOND_ARG(time_it_params TIME_IT_NOT_EXPOSED__FIRST_ARG, __VA_ARGS__);) \ TIME_IT_NOT_EXPOSED__INIT_RES(type, time_it_params.repeat);\ TIME_IT_NOT_EXPOSED__IF_REPEAT(type, for(size_t i = 0; i < time_it_params.repeat; i++){) \ double time_it_time = 0; \ for(size_t j = 0; j < time_it_params.number; j++){ \ struct timespec time_it_start, time_it_stop; \ clock_gettime(CLOCK_MONOTONIC, &time_it_start); \ code; \ clock_gettime(CLOCK_MONOTONIC, &time_it_stop); \ time_it_time += ((time_it_stop.tv_sec - time_it_start.tv_sec) + (time_it_stop.tv_nsec - time_it_start.tv_nsec) / 1000000000.0); \ }\ TIME_IT_NOT_EXPOSED__WRITE_RES(type, time_it_time); \ TIME_IT_NOT_EXPOSED__IF_REPEAT(type, }) \ res;\ }) #define TIME_IT_NOT_EXPOSED__MAYBE_SECOND_ARG(macro, a1, ...) __VA_OPT__(macro(__VA_ARGS__)) #define TIME_IT_NOT_EXPOSED__FIRST_ARG(a1, ...) a1 #define TIME_IT_NOT_EXPOSED__INIT_RES_REPEAT(repeat) double_arr_t *res = double_arr_init(repeat) #define TIME_IT_NOT_EXPOSED__INIT_RES_(_) double res = 0 #define TIME_IT_NOT_EXPOSED__INIT_RES(type, repeat) TIME_IT_NOT_EXPOSED__INIT_RES_ ## type (repeat) #define TIME_IT_NOT_EXPOSED__WRITE_RES_REPEAT(value) double_arr_push(res, value) #define TIME_IT_NOT_EXPOSED__WRITE_RES_(value) res = value #define TIME_IT_NOT_EXPOSED__WRITE_RES(type, value) TIME_IT_NOT_EXPOSED__WRITE_RES_ ## type(value) #define TIME_IT_NOT_EXPOSED__IF_REPEAT_REPEAT(code, ...) code __VA_OPT__(,) #define TIME_IT_NOT_EXPOSED__IF_REPEAT_(...) #define TIME_IT_NOT_EXPOSED__IF_REPEAT(type, ...) TIME_IT_NOT_EXPOSED__IF_REPEAT_ ## type (__VA_ARGS__) #endif //TIME_IT_H