Measure code execution time
//
// Copyright © 2012 Yuri Kotov
//
#import <mach/mach_time.h>
#import <Foundation/Foundation.h>
uint64_t ADVGetExecutionTime(void(^block)())
{
NSCAssert(block, @"'block' parameter can't be nil");
static mach_timebase_info_data_t timebase = {};
uint64_t start = mach_absolute_time();
block();
uint64_t end = mach_absolute_time();
if (0 == timebase.denom)
{
mach_timebase_info(&timebase);
}
return (end - start) * timebase.numer / timebase.denom;
}
uint64_t ADVGetMedianExecutionTime(size_t iterations, void(^block)())
{
NSCAssert(0 < iterations, @"'iterations' parameter must be positive");
size_t size = iterations * sizeof(uint64_t);
uint64_t *samples = malloc(size);
if (!samples)
{
fprintf(stderr, "%s: Unable to allocate %zu bytes", __func__, size);
return UINT64_MAX;
}
for (size_t i = 0; i < iterations; ++i)
{
samples[i] = ADVGetExecutionTime(block);
}
qsort_b(samples, iterations, sizeof(uint64_t), ^(const void *a, const void *b) {
return (int)(*(uint64_t*)a - *(uint64_t*)b);
});
uint64_t mid = iterations / 2;
uint64_t result = (iterations & 1) ? samples[mid] : (samples[mid] + samples[mid + 1]) / 2;
free(samples);
return result;
}
uint64_t ADVGetExecutionStats(size_t iterations, uint64_t *deviation, void(^block)())
{
// TODO: Implement this function
return 0;
}
//
// Copyright © 2012 Yuri Kotov
//
/*!
@function ADVGetExecutionTime
@abstract Measure code execution time
@param block
code block to execute
@result elapsed time (in nanoseconds)
*/
extern uint64_t ADVGetExecutionTime(void(^block)());
/*!
@function ADVGetMedianExecutionTime
@abstract Measure median code execution time
@param iterations
number of iterations
@param block
code block to execute
@result median elapsed time (in nanoseconds) or UINT64_MAX (in case of failure)
*/
extern uint64_t ADVGetMedianExecutionTime(size_t iterations, void(^block)());
/*!
@function ADVGetMedianExecutionTime
@abstract Measure code execution time stats, e.g. "52100 ns (±150 ns)"
@param iterations
number of iterations
@param deviation
standard deviation (returned by reference)
@param block
code block to execute
@result median elapsed time (in nanoseconds) or UINT64_MAX (in case of failure)
*/
extern uint64_t ADVGetExecutionStats(size_t iterations, uint64_t *deviation, void(^block)());