#pragma once #include #if defined(__AVR__) #include #else #include #endif #if !defined(MILLIS_PER_SEC) #define MILLIS_PER_SEC 1000ULL #endif #if !defined(MICROS_PER_SEC) #define MICROS_PER_SEC (MILLIS_PER_SEC*1000) #endif #if !defined(NANOS_PER_SEC) #define NANOS_PER_SEC (MICROS_PER_SEC*1000) #endif class timer { private: #if defined(__AVR__) uint32_t start_time; uint32_t end_time; #else struct timeval start_time; struct timeval end_time; #endif public: timer() { } void start() { #if defined(__AVR__) start_time = micros(); #else gettimeofday(&start_time, NULL); #endif } void stop() { #if defined(__AVR__) end_time = micros(); #else gettimeofday(&end_time, NULL); #endif } uint32_t duration_micros() { #if defined(__AVR__) return end_time-start_time; #else return (uint32_t)(((end_time.tv_sec - start_time.tv_sec) * MICROS_PER_SEC) + (end_time.tv_usec - start_time.tv_usec)); #endif } }; template void measure_executiontime(uint16_t iterations, TLoop from, TLoop to, TLoop step, timer &measure, TParam param, void (*pTestFun)(TLoop, TParam)) { measure.start(); for (uint16_t loop=0; loop struct execution_time { TParam result; uint32_t durationMicros; }; template struct comparative_execution_times { execution_time timeA; execution_time timeB; }; template comparative_execution_times compare_executiontime(uint16_t iterations, TLoop from, TLoop to, TLoop step, void (*pTestFunA)(TLoop, TParam&), void (*pTestFunB)(TLoop, TParam&)) { timer timerA; TParam paramA = 0; measure_executiontime(iterations, from, to, step, timerA, paramA, pTestFunA); timer timerB; TParam paramB = 0; measure_executiontime(iterations, from, to, step, timerB, paramB, pTestFunB); char buffer[128]; sprintf(buffer, "Timing: %" PRIu32 ", %" PRIu32, timerA.duration_micros(), timerB.duration_micros()); TEST_MESSAGE(buffer); return comparative_execution_times { .timeA = execution_time { .result = paramA, .durationMicros = timerA.duration_micros()}, .timeB = execution_time { .result = paramB, .durationMicros = timerB.duration_micros()} }; }