mirror of
https://gitlab.com/80486DX2-66/gists
synced 2024-11-08 18:02:23 +05:30
portable_basename.* + clock_hr_microsec.*: split and improve
This commit is contained in:
parent
841472299f
commit
e7272e8043
133
c-programming/benchmarking/clock_hr_microsec.c
Normal file
133
c-programming/benchmarking/clock_hr_microsec.c
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* clock_hr_microsec.c
|
||||||
|
*
|
||||||
|
* A small library to measure execution time of code as precisely as possible.
|
||||||
|
*
|
||||||
|
* TODO: Use fixed point arithmetics
|
||||||
|
*
|
||||||
|
* Author: Intel A80486DX2-66
|
||||||
|
* License: Unlicense
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "clock_hr_microsec.h"
|
||||||
|
|
||||||
|
// macros
|
||||||
|
#if defined(SYS_NT)
|
||||||
|
static LONGLONG QPF_frequency;
|
||||||
|
|
||||||
|
# define WinAPI_perror_COMMON_MACRO \
|
||||||
|
fprintf(stderr, "%s: %lu, %s", s, errorCode, errorString)
|
||||||
|
# define CLOCK_HR_DIFFTIME_MS(t2, t1) \
|
||||||
|
(((clock_hr_microsec_t) ((t2) - (t1))) / \
|
||||||
|
((clock_hr_microsec_t) QPF_frequency))
|
||||||
|
|
||||||
|
#elif defined(SYS_UNIX)
|
||||||
|
# define CLOCK_HR_DIFFTIME_MS(t2, t1) \
|
||||||
|
((t2) - (t1))
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define CLOCK_HR_DIFFTIME_MS(t2, t1) \
|
||||||
|
((clock_hr_microsec_t) ((t2) - (t1)) * 1000000.L) / \
|
||||||
|
((clock_hr_microsec_t) CLOCKS_PER_SEC)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// function implementations
|
||||||
|
void clock_hr_microsec_init(void) {
|
||||||
|
# ifdef SYS_NT
|
||||||
|
// set console output code page to the native one
|
||||||
|
SetConsoleOutputCP(GetACP());
|
||||||
|
|
||||||
|
// get CPU frequency
|
||||||
|
LARGE_INTEGER freq;
|
||||||
|
if (!QueryPerformanceFrequency(&freq)) {
|
||||||
|
WinAPI_perror("QueryPerformanceFrequency");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPF_frequency = freq.QuadPart;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
long double clock_hr_microsec(void) {
|
||||||
|
# if defined(SYS_NT)
|
||||||
|
// FIXME: less accurate than Unix
|
||||||
|
|
||||||
|
LARGE_INTEGER counter;
|
||||||
|
if (!QueryPerformanceCounter(&counter)) {
|
||||||
|
WinAPI_perror("QueryPerformanceCounter");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return (long double) (counter.QuadPart * 1000000ULL);
|
||||||
|
# elif defined(SYS_UNIX)
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||||
|
return ((long double) (ts.tv_sec * 1000000000ULL + ts.tv_nsec)) / 1000.l;
|
||||||
|
# else
|
||||||
|
return (long double) (clock() * 1000000ULL);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_hr_microsec_t clock_hr_microsec_diff(clock_hr_microsec_t a,
|
||||||
|
clock_hr_microsec_t b) {
|
||||||
|
return CLOCK_HR_DIFFTIME_MS(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef SYS_NT
|
||||||
|
void WinAPI_perror(const char* s) {
|
||||||
|
DWORD errorCode = GetLastError();
|
||||||
|
LPSTR errorString = NULL;
|
||||||
|
FormatMessage(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
errorCode,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPSTR)&errorString,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (errorString == NULL) {
|
||||||
|
errorString = "???\n";
|
||||||
|
WinAPI_perror_COMMON_MACRO;
|
||||||
|
} else {
|
||||||
|
WinAPI_perror_COMMON_MACRO;
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
# include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
clock_hr_microsec_init();
|
||||||
|
|
||||||
|
clock_hr_microsec_t t1 = 0, t2 = 0;
|
||||||
|
|
||||||
|
t1 = clock_hr_microsec();
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
printf("[");
|
||||||
|
for (int i = 1; i <= 240; i += 3, counter++) {
|
||||||
|
if (i >= 8 && (counter & 7) == 0) {
|
||||||
|
printf("\n ");
|
||||||
|
}
|
||||||
|
printf("0x%02X", i);
|
||||||
|
|
||||||
|
if (i <= 237) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts("]\n");
|
||||||
|
|
||||||
|
t2 = clock_hr_microsec();
|
||||||
|
|
||||||
|
printf("Counter = %d\n"
|
||||||
|
"Time: %" CLOCK_HR_MICROSEC_PRI " microsec\n",
|
||||||
|
counter,
|
||||||
|
clock_hr_microsec_diff(t2, t1));
|
||||||
|
}
|
||||||
|
#endif
|
43
c-programming/benchmarking/clock_hr_microsec.h
Normal file
43
c-programming/benchmarking/clock_hr_microsec.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* clock_hr_microsec.h
|
||||||
|
*
|
||||||
|
* Author: Intel A80486DX2-66
|
||||||
|
* License: Unlicense
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CLOCK_HR_MICROSEC_H
|
||||||
|
#define _CLOCK_HR_MICROSEC_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// typedefs
|
||||||
|
typedef long double clock_hr_microsec_t;
|
||||||
|
|
||||||
|
// print specifiers
|
||||||
|
#define CLOCK_HR_MICROSEC_PRI ".3Lf"
|
||||||
|
|
||||||
|
// system identification
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define SYS_NT
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
# define SYS_UNIX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// macros
|
||||||
|
#if defined(SYS_UNIX) && !defined(CLOCK_MONOTONIC_RAW)
|
||||||
|
# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// function prototypes
|
||||||
|
void clock_hr_microsec_init(void);
|
||||||
|
clock_hr_microsec_t clock_hr_microsec(void);
|
||||||
|
clock_hr_microsec_t clock_hr_microsec_diff(clock_hr_microsec_t a,
|
||||||
|
clock_hr_microsec_t b);
|
||||||
|
#ifdef SYS_NT
|
||||||
|
void WinAPI_perror(const char* s);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _CLOCK_HR_MICROSEC_H */
|
@ -44,215 +44,3 @@ char* portable_basename(const char* raw_path) {
|
|||||||
|
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
# include <inttypes.h>
|
|
||||||
# include <stdbool.h>
|
|
||||||
# include <stdio.h>
|
|
||||||
# include <time.h>
|
|
||||||
|
|
||||||
// system identification
|
|
||||||
# ifdef _WIN32
|
|
||||||
# define SYS_NT
|
|
||||||
# include <windows.h>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if defined(__unix__) || defined(__APPLE__)
|
|
||||||
# define SYS_UNIX
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// macros
|
|
||||||
# if defined(SYS_UNIX) && !defined(CLOCK_MONOTONIC_RAW)
|
|
||||||
# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// function prototypes
|
|
||||||
long double clock_hr_microsec(void);
|
|
||||||
# ifdef SYS_NT
|
|
||||||
void WinAPI_perror(const char* s);
|
|
||||||
# endif
|
|
||||||
static void func_expect(const char* path, const char* expected_output,
|
|
||||||
bool expect_to_succeed);
|
|
||||||
|
|
||||||
long double clock_hr_microsec(void) {
|
|
||||||
# ifdef SYS_NT
|
|
||||||
// FIXME: less accurate than Unix
|
|
||||||
|
|
||||||
LARGE_INTEGER counter;
|
|
||||||
if (!QueryPerformanceCounter(&counter)) {
|
|
||||||
WinAPI_perror("QueryPerformanceCounter");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return (long double) (counter.QuadPart * 1000000ULL);
|
|
||||||
# elif SYS_UNIX
|
|
||||||
struct timespec ts;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
|
||||||
return ((long double) (ts.tv_sec * 1000000000ULL + ts.tv_nsec)) / 1000.l;
|
|
||||||
# else
|
|
||||||
return (long double) (clock() * 1000000ULL);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// macros
|
|
||||||
# ifdef SYS_NT
|
|
||||||
# define WinAPI_perror_COMMON_MACRO \
|
|
||||||
fprintf(stderr, "%s: %lu, %s", s, errorCode, errorString)
|
|
||||||
|
|
||||||
// function implementations
|
|
||||||
void WinAPI_perror(const char* s) {
|
|
||||||
DWORD errorCode = GetLastError();
|
|
||||||
LPSTR errorString = NULL;
|
|
||||||
FormatMessage(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL,
|
|
||||||
errorCode,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
(LPSTR)&errorString,
|
|
||||||
0,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (errorString == NULL) {
|
|
||||||
errorString = "???\n";
|
|
||||||
WinAPI_perror_COMMON_MACRO;
|
|
||||||
} else {
|
|
||||||
WinAPI_perror_COMMON_MACRO;
|
|
||||||
LocalFree(errorString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// macros
|
|
||||||
# if defined(SYS_NT)
|
|
||||||
LONGLONG QPF_frequency;
|
|
||||||
# define CLOCK_HR_DIFFTIME_MS(t2, t1) \
|
|
||||||
((long double) ((t2) - (t1))) / ((long double) QPF_frequency)
|
|
||||||
# elif defined(SYS_UNIX)
|
|
||||||
# define CLOCK_HR_DIFFTIME_MS(t2, t1) \
|
|
||||||
((t2) - (t1))
|
|
||||||
# else
|
|
||||||
# define CLOCK_HR_DIFFTIME_MS(t2, t1) \
|
|
||||||
((long double) ((t2) - (t1)) * 1000000.L) / \
|
|
||||||
((long double) CLOCKS_PER_SEC)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// global variables
|
|
||||||
uintmax_t tests_failed = 0;
|
|
||||||
|
|
||||||
// function implementations
|
|
||||||
static void func_expect(const char* path, const char* expected_output,
|
|
||||||
bool expect_to_succeed) {
|
|
||||||
long double t1 = 0, t2 = 0;
|
|
||||||
|
|
||||||
t1 = clock_hr_microsec();
|
|
||||||
char* output = portable_basename(path);
|
|
||||||
t2 = clock_hr_microsec();
|
|
||||||
if (output == NULL) {
|
|
||||||
perror("portable_basename");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* caption = expect_to_succeed ? "Expected output "
|
|
||||||
: "Unexpected output";
|
|
||||||
long double t = CLOCK_HR_DIFFTIME_MS(t2, t1);
|
|
||||||
printf("Input path : '%s'\n"
|
|
||||||
"%s: '%s'\n"
|
|
||||||
"Actual output : '%s'\n"
|
|
||||||
"Time, clock_t : %.3Lf microsec\n"
|
|
||||||
"Test result : ", path, caption, expected_output, output, t);
|
|
||||||
if ((bool) (strcmp(output, expected_output)) == expect_to_succeed) {
|
|
||||||
tests_failed++;
|
|
||||||
free(output);
|
|
||||||
|
|
||||||
puts("Failed!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
puts("Passed\n");
|
|
||||||
|
|
||||||
free(output);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// macros
|
|
||||||
#define STRINGIZE(x) #x
|
|
||||||
#define INT2STR(x) STRINGIZE(x)
|
|
||||||
|
|
||||||
#define TIMES_TO_CALL 65535
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
# ifdef SYS_NT
|
|
||||||
// set console output code page to the native one
|
|
||||||
SetConsoleOutputCP(GetACP());
|
|
||||||
|
|
||||||
// get CPU frequency
|
|
||||||
LARGE_INTEGER freq;
|
|
||||||
if (!QueryPerformanceFrequency(&freq)) {
|
|
||||||
WinAPI_perror("QueryPerformanceFrequency");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPF_frequency = freq.QuadPart;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// positive tests
|
|
||||||
func_expect("/", "", true);
|
|
||||||
func_expect("/usr/include/stdlib.h", "stdlib.h", true);
|
|
||||||
func_expect("C:\\Windows\\Fonts\\consola.ttf", "consola.ttf", true);
|
|
||||||
func_expect("\\..\\..\\directory\\.e.x.e.c.u.t.a.b.l.e.",
|
|
||||||
".e.x.e.c.u.t.a.b.l.e.", true);
|
|
||||||
|
|
||||||
// negative tests
|
|
||||||
func_expect("/a/.b.c.", "b.c", false);
|
|
||||||
func_expect("/a/.b.c.", ".b.c", false);
|
|
||||||
func_expect("/a/.b.c.", "b.c.", false);
|
|
||||||
func_expect("/a/.b.c.\\", ".b.c.", false);
|
|
||||||
|
|
||||||
printf("Failed tests: %" PRIuMAX "\n", tests_failed);
|
|
||||||
|
|
||||||
// timing test
|
|
||||||
puts("\nBenchmarking (" INT2STR(TIMES_TO_CALL) " calls):");
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
#define BENCHMARKING_STRING_SET \
|
|
||||||
"a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r\\s\\t\\u\\v\\w\\x\\y\\z\\.\\file", \
|
|
||||||
"/mnt/cdrom/usr/bin/include/library/test_files/test.h"
|
|
||||||
|
|
||||||
const char* string_set[] = {
|
|
||||||
BENCHMARKING_STRING_SET,
|
|
||||||
// HACK: try to prevent caching by using different pointers
|
|
||||||
BENCHMARKING_STRING_SET,
|
|
||||||
BENCHMARKING_STRING_SET,
|
|
||||||
BENCHMARKING_STRING_SET
|
|
||||||
};
|
|
||||||
|
|
||||||
const size_t string_set_len = sizeof(string_set) / sizeof(char*);
|
|
||||||
|
|
||||||
long double t_beginning = 0, t_end = 0;
|
|
||||||
long double t_total = 0.l;
|
|
||||||
|
|
||||||
for (uint_fast16_t i = 0; i < TIMES_TO_CALL; i++) {
|
|
||||||
const char* selected_string = string_set[i % string_set_len];
|
|
||||||
|
|
||||||
t_beginning = clock_hr_microsec();
|
|
||||||
char* output = portable_basename(selected_string);
|
|
||||||
t_end = clock_hr_microsec();
|
|
||||||
|
|
||||||
if (output == NULL) {
|
|
||||||
perror("portable_basename");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(output);
|
|
||||||
|
|
||||||
t_total += CLOCK_HR_DIFFTIME_MS(t_end, t_beginning);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Total time: %.3Lf microsec, avg. %.3Lf microsec\n", t_total,
|
|
||||||
t_total / ((long double) TIMES_TO_CALL));
|
|
||||||
|
|
||||||
return (tests_failed > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TEST */
|
|
||||||
|
125
c-programming/strings/portable_basename.test.c
Normal file
125
c-programming/strings/portable_basename.test.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* portable_basename.test.c
|
||||||
|
*
|
||||||
|
* Also compile `portable_basename.c` and `../benchmarking/clock_hr_microsec.c`
|
||||||
|
*
|
||||||
|
* Author: Intel A80486DX2-66
|
||||||
|
* License: Unlicense
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "portable_basename.h"
|
||||||
|
#include "../benchmarking/clock_hr_microsec.h"
|
||||||
|
|
||||||
|
// global variables
|
||||||
|
uintmax_t tests_failed = 0;
|
||||||
|
|
||||||
|
// function prototypes
|
||||||
|
static void func_expect(const char* path, const char* expected_output,
|
||||||
|
bool expect_to_succeed);
|
||||||
|
|
||||||
|
// function implementations
|
||||||
|
static void func_expect(const char* path, const char* expected_output,
|
||||||
|
bool expect_to_succeed) {
|
||||||
|
clock_hr_microsec_t t1 = 0, t2 = 0;
|
||||||
|
|
||||||
|
t1 = clock_hr_microsec();
|
||||||
|
char* output = portable_basename(path);
|
||||||
|
t2 = clock_hr_microsec();
|
||||||
|
if (output == NULL) {
|
||||||
|
perror("portable_basename");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* caption = expect_to_succeed ? "Expected output "
|
||||||
|
: "Unexpected output";
|
||||||
|
clock_hr_microsec_t t = clock_hr_microsec_diff(t2, t1);
|
||||||
|
printf("Input path : '%s'\n"
|
||||||
|
"%s: '%s'\n"
|
||||||
|
"Actual output : '%s'\n"
|
||||||
|
"Time, clock_t : %" CLOCK_HR_MICROSEC_PRI " microsec\n"
|
||||||
|
"Test result : ", path, caption, expected_output, output, t);
|
||||||
|
if ((bool) (strcmp(output, expected_output)) == expect_to_succeed) {
|
||||||
|
tests_failed++;
|
||||||
|
free(output);
|
||||||
|
|
||||||
|
puts("Failed!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
puts("Passed\n");
|
||||||
|
|
||||||
|
free(output);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// macros
|
||||||
|
#define STRINGIZE(x) #x
|
||||||
|
#define INT2STR(x) STRINGIZE(x)
|
||||||
|
|
||||||
|
#define TIMES_TO_CALL 65535
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
clock_hr_microsec_init();
|
||||||
|
|
||||||
|
// positive tests
|
||||||
|
func_expect("/", "", true);
|
||||||
|
func_expect("/usr/include/stdlib.h", "stdlib.h", true);
|
||||||
|
func_expect("C:\\Windows\\Fonts\\consola.ttf", "consola.ttf", true);
|
||||||
|
func_expect("\\..\\..\\directory\\.e.x.e.c.u.t.a.b.l.e.",
|
||||||
|
".e.x.e.c.u.t.a.b.l.e.", true);
|
||||||
|
|
||||||
|
// negative tests
|
||||||
|
func_expect("/a/.b.c.", "b.c", false);
|
||||||
|
func_expect("/a/.b.c.", ".b.c", false);
|
||||||
|
func_expect("/a/.b.c.", "b.c.", false);
|
||||||
|
func_expect("/a/.b.c.\\", ".b.c.", false);
|
||||||
|
|
||||||
|
printf("Failed tests: %" PRIuMAX "\n", tests_failed);
|
||||||
|
|
||||||
|
// timing test
|
||||||
|
puts("\nBenchmarking (" INT2STR(TIMES_TO_CALL) " calls):");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
#define BENCHMARKING_STRING_SET \
|
||||||
|
"a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r\\s\\t\\u\\v\\w\\x\\y\\z\\.\\file", \
|
||||||
|
"/mnt/cdrom/usr/bin/include/library/test_files/test.h"
|
||||||
|
|
||||||
|
const char* string_set[] = {
|
||||||
|
BENCHMARKING_STRING_SET,
|
||||||
|
// HACK: try to prevent caching by using different pointers
|
||||||
|
BENCHMARKING_STRING_SET,
|
||||||
|
BENCHMARKING_STRING_SET,
|
||||||
|
BENCHMARKING_STRING_SET
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t string_set_len = sizeof(string_set) / sizeof(char*);
|
||||||
|
|
||||||
|
clock_hr_microsec_t t_beginning = 0, t_end = 0;
|
||||||
|
clock_hr_microsec_t t_total = 0.l;
|
||||||
|
|
||||||
|
for (uint_fast16_t i = 0; i < TIMES_TO_CALL; i++) {
|
||||||
|
const char* selected_string = string_set[i % string_set_len];
|
||||||
|
|
||||||
|
t_beginning = clock_hr_microsec();
|
||||||
|
char* output = portable_basename(selected_string);
|
||||||
|
t_end = clock_hr_microsec();
|
||||||
|
|
||||||
|
if (output == NULL) {
|
||||||
|
perror("portable_basename");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(output);
|
||||||
|
|
||||||
|
t_total += clock_hr_microsec_diff(t_end, t_beginning);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Total time: %" CLOCK_HR_MICROSEC_PRI " microsec, avg. "
|
||||||
|
"%" CLOCK_HR_MICROSEC_PRI "microsec\n", t_total,
|
||||||
|
t_total / ((long double) TIMES_TO_CALL));
|
||||||
|
|
||||||
|
return (tests_failed > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user