Created
September 29, 2023 10:42
-
-
Save saagarjha/1a82fddb67f5870525e104cb2f5454e9 to your computer and use it in GitHub Desktop.
Test whether mmap or read is faster on your computer
This file contains 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
// As seen on: | |
// https://federated.saagarjha.com/notice/AaEMQpJBSbxhLyxYzg | |
// https://twitter.com/_saagarjha/status/1707423903969341949 | |
// Compiling: gcc mmap_vs_read.c -O3 -o mmap_vs_read | |
// Usage: ./mmap_vs_read <bigfile> <mmap|read> | |
#include <fcntl.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/fcntl.h> | |
#include <sys/mman.h> | |
#include <unistd.h> | |
unsigned char hash_buffer(unsigned char *buffer, size_t size) { | |
unsigned char hash = 0; | |
while (size--) { | |
hash ^= *buffer++; | |
} | |
return hash; | |
} | |
unsigned char test_read(int fd) { | |
unsigned char hash = 0; | |
size_t buffer_size = sysconf(_SC_PAGESIZE) * 16; | |
unsigned char *buffer = malloc(buffer_size); | |
ssize_t size = 0; | |
while (size = read(fd, buffer, buffer_size), size > 0) { | |
hash ^= hash_buffer(buffer, size); | |
} | |
return hash; | |
} | |
unsigned char test_mmap(int fd) { | |
off_t size = lseek(fd, 0, SEEK_END); | |
unsigned char *buffer = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); | |
return hash_buffer(buffer, size); | |
} | |
int main(int argc, char **argv) { | |
int fd = open(*++argv, O_RDONLY); | |
char *choice = *++argv; | |
if (!choice) { | |
return EXIT_FAILURE; | |
} else if (!strcmp(choice, "read")) { | |
return test_read(fd); | |
} else if (!strcmp(choice, "mmap")) { | |
return test_mmap(fd); | |
} else { | |
return EXIT_FAILURE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And on the big FreeBSD system:
The big Mac and FreeBSD systems each have hundreds of gigabytes of RAM, and all three systems are SSD-only. (However: on the big FreeSBD system, I used
/tmp
which istmpfs
; on the smaller one, which doesn't have as much RAM, the test file was on a ZFS dataset.)