60 lines
1.7 KiB
C
60 lines
1.7 KiB
C
/* timeit — run a command once and print its elapsed wall time in µs.
|
|
*
|
|
* The benchmark harness races fastwc against several wc implementations.
|
|
* Timing both sides by wrapping the command in `date +%s%N` forks added
|
|
* over a millisecond of noise per sample — more than the whole run on a
|
|
* small case — so every sub-millisecond race was decided by fork jitter,
|
|
* not by speed. This helper measures a plain fork + exec + wait with
|
|
* clock_gettime and prints the elapsed microseconds on its own stdout.
|
|
* The timed command's output is discarded, exactly as the old date
|
|
* wrapper did, so capture_count (which runs the command directly) is the
|
|
* only path that sees real output.
|
|
*
|
|
* usage: timeit <cmd> [arg...]
|
|
*/
|
|
#define _POSIX_C_SOURCE 200809L
|
|
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <sys/wait.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
struct timespec t0, t1;
|
|
pid_t pid;
|
|
int nullfd;
|
|
|
|
if (argc < 2)
|
|
return 2;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &t0);
|
|
|
|
pid = fork();
|
|
if (pid < 0)
|
|
return 2;
|
|
if (pid == 0)
|
|
{
|
|
/* child: run the timed command with its output thrown away */
|
|
nullfd = open("/dev/null", O_WRONLY);
|
|
if (nullfd >= 0)
|
|
{
|
|
dup2(nullfd, STDOUT_FILENO);
|
|
dup2(nullfd, STDERR_FILENO);
|
|
close(nullfd);
|
|
}
|
|
execvp(argv[1], &argv[1]);
|
|
_exit(127);
|
|
}
|
|
|
|
if (waitpid(pid, NULL, 0) < 0)
|
|
return 2;
|
|
clock_gettime(CLOCK_MONOTONIC, &t1);
|
|
|
|
printf("%lld\n",
|
|
((long long)(t1.tv_sec - t0.tv_sec) * 1000000000LL
|
|
+ (t1.tv_nsec - t0.tv_nsec)) / 1000);
|
|
return 0;
|
|
}
|