Skip to content

Instantly share code, notes, and snippets.

@stephanGarland
Created July 14, 2024 15:01
Show Gist options
  • Save stephanGarland/f6b7a13585c0caf9eb64b035b15b9882 to your computer and use it in GitHub Desktop.
Save stephanGarland/f6b7a13585c0caf9eb64b035b15b9882 to your computer and use it in GitHub Desktop.
Demonstrating arc4random vs. ul_random_get_bytes performance difference

Results

All programs compiled with -O3, using clang v15.0.0 on MacOS, and gcc 10.2.1 on Linux. Mac was an M1 Air base model (8 GiB RAM), with low power mode disabled. Linux server was a Debian 11 VM with a Xeon E5-2650 v2 @ 2.60GHz, and 64 GiB of PC3-12800R RAM.

Linux

❯ ./uuid_runner.sh
          program | num_uuids |  time_(msec)
./uuid_util_linux |         1 |     0.030000
./uuid_arc4random |         1 |     0.057000
./uuid_util_linux |        10 |     0.096000
./uuid_arc4random |        10 |     0.041000
./uuid_util_linux |       100 |     0.938000
./uuid_arc4random |       100 |     0.116000
./uuid_util_linux |      1000 |     6.935000
./uuid_arc4random |      1000 |     0.728000
./uuid_util_linux |     10000 |    69.253000
./uuid_arc4random |     10000 |     5.134000
./uuid_util_linux |    100000 |   699.057000
./uuid_arc4random |    100000 |    58.544000
./uuid_util_linux |   1000000 |  6806.215000
./uuid_arc4random |   1000000 |   562.811000
./uuid_util_linux |  10000000 | 71995.862000
./uuid_arc4random |  10000000 |  5585.596000

MacOS

❯ ./uuid_runner.sh
./uuid_util_linux  1         0.029000
./uuid_arc4random  1         0.001000
./uuid_util_linux  10        0.157000
./uuid_arc4random  10        0.006000
./uuid_util_linux  100       1.371000
./uuid_arc4random  100       0.040000
./uuid_util_linux  1000      11.717000
./uuid_arc4random  1000      0.302000
./uuid_util_linux  10000     82.895000
./uuid_arc4random  10000     2.237000
./uuid_util_linux  100000    780.911000
./uuid_arc4random  100000    22.371000
./uuid_util_linux  1000000   7808.189000
./uuid_arc4random  1000000   223.745000
./uuid_util_linux  10000000  78562.432000
./uuid_arc4random  10000000  2237.202000

Code

NOTE: I am not a C programmer. I am aware that atoi() has issues; I do not care in this instance.

uuid_util_linux

On MacOS, you'll need to explicitly pass a -L/PATH/TO/UTIL-LINUX and -luuid, otherwise the Mac's native libuuid will be used.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <uuid/uuid.h>

int main(int argc, char *argv[]) {
    uuid_t uuid;
    char uuid_str[37];
    clock_t start, end;
    double cpu_time_used;

    if (argc != 2) {
        fprintf(stderr, "usage: %s %s\n", argv[0], " <integer>");
        exit(1);
    }

    int NUM_UUIDS = atoi(argv[1]);
    start = clock();

    for (int i = 0; i < NUM_UUIDS; i++) {
        uuid_generate(uuid);
        uuid_unparse(uuid, uuid_str);
    }

    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

    printf("%f\n", cpu_time_used * 1000);
    return 0;
}

uuid_arc4random

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <uuid/uuid.h>

extern void arc4random_buf(void *buf, size_t nbytes);

int main(int argc, char *argv[]) {
    uuid_t uuid;
    char uuid_str[37];
    clock_t start, end;
    double cpu_time_used;

    if (argc != 2) {
        fprintf(stderr, "usage: %s %s\n", argv[0], " <integer>");
        exit(1);
    }

    int NUM_UUIDS = atoi(argv[1]);
    start = clock();

    for (int i = 0; i < NUM_UUIDS; i++) {
        arc4random_buf(uuid, 16);
        uuid[6] = (uuid[6] & 0x0f) | 0x40;
        uuid[8] = (uuid[8] & 0x3f) | 0x80;
        uuid_unparse(uuid, uuid_str);
    }

    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

    printf("%f\n", cpu_time_used * 1000);

    return 0;
}

uuid_runner.sh

#!/usr/bin/env bash

num_runs=(1 10 100 1000 10000 100000 1000000 10000000)
progs=("./uuid_util_linux" "./uuid_arc4random")

header="program,num_uuids,time_(msec)"

for num in "${num_runs[@]}"; do
    for prog in "${progs[@]}"; do
        run_time=$(eval "${prog}" "${num}")
        echo "${prog} ${num} ${run_time}"
    done
done | column -t -s " | "

# On Linux, you can instead call column like this for nicer output
# column -t --output-separator " | " --table-columns "${header}" --table-right "${header}"
# You can also kludge Mac output by doing a one-time loop calling ${header}
# as the first entry to be printed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment