Created
July 1, 2025 15:42
-
-
Save ncruces/24849719d73ed521fa2dbd510932ecd8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <time.h> | |
#define DoNotOptimize(value) \ | |
({ \ | |
typeof(value) v = value; \ | |
asm volatile("" : "+r,m"(v) : : "memory"); \ | |
value; \ | |
}) | |
#define NANOS (int64_t)(1e9) | |
#define MEGABYTE (1024 * 1024) | |
static int64_t timespec_to_nsec(const struct timespec a) { | |
return (int64_t)a.tv_sec * NANOS + a.tv_nsec; | |
} | |
void bench_strlen() { | |
char *buffer = malloc(MEGABYTE); | |
memset(buffer, 5, MEGABYTE); | |
buffer[MEGABYTE - 1] = 0; | |
// Test various lengths. | |
for (size_t i = 1; i < MEGABYTE; i = i * 3 - 1) { | |
buffer[i] = 0; | |
} | |
struct timespec start, end; | |
clock_gettime(CLOCK_MONOTONIC, &start); | |
for (size_t i = 0; i < MEGABYTE;) { | |
i += 1 + DoNotOptimize(strlen(buffer + i)); | |
} | |
clock_gettime(CLOCK_MONOTONIC, &end); | |
int64_t delta = timespec_to_nsec(end) - timespec_to_nsec(start); | |
printf("strlen: %f MB/s\n", (float)NANOS / (float)delta); | |
free(buffer); | |
} | |
void bench_memchr() { | |
char *buffer = malloc(MEGABYTE); | |
memset(buffer, 5, MEGABYTE); | |
// Test various lengths. | |
for (size_t i = 1; i < MEGABYTE; i = i * 3 - 1) { | |
buffer[i] = 7; | |
} | |
struct timespec start, end; | |
clock_gettime(CLOCK_MONOTONIC, &start); | |
for (char *ptr = buffer; ptr < buffer + MEGABYTE; ptr++) { | |
ptrdiff_t avail = (buffer + MEGABYTE) - ptr; | |
ptr = DoNotOptimize(memchr(ptr, 7, avail)); | |
if (ptr == NULL) break; | |
} | |
clock_gettime(CLOCK_MONOTONIC, &end); | |
int64_t delta = timespec_to_nsec(end) - timespec_to_nsec(start); | |
printf("memchr: %f MB/s\n", (float)NANOS / (float)delta); | |
free(buffer); | |
} | |
int main(void) { | |
for (int i = 0; i < 10; i++) { | |
bench_strlen(); | |
bench_memchr(); | |
} | |
return 0; | |
} |
I just dropped it next to the unit tests in test/src/misc/
.
Given the infra, just printing some output fails the test, but that was good enough “for now”. Then go look at the failure.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So I can replicate: what commands do you use to compile and run this?