Optimizing Rust Binaries: Observation of Musl versus Glibc and Jemalloc versus System Alloc

Someone on reddit asked for a ripgrep data point, so I did a comparison across the full matrix for ripgrep using its benchmark suite, but I couldn't find any meaningful differences. The benchmark command I ran was roughly:

cd clones/ripgrep/benchsuite
for libc in glibc musl; do
    for alloc in jemalloc system; do
        outdir=./runs/2016-12-24-archlinux-$libc-$alloc
        mkdir $outdir
        ./benchsuite --disabled ag,ucg,pt,sift,git,grep --dir /data/benchsuite/ --raw $outdir/raw.csv > $outdir/summary
    done
done

For glibc, the compile command I used was:

$ RUSTFLAGS="-C target-cpu=native" cargo build --release --features 'simd-accel avx-accel'

For musl:

$ RUSTFLAGS="-C target-cpu=native" cargo build --release --features 'simd-accel avx-accel' --target x86_64-unknown-linux-musl

Rust version:

$ rustc --version
rustc 1.15.0-nightly (71c06a56a 2016-12-18)

For the system allocator, I added #[feature(alloc_system)] and extern crate alloc_system; to my src/main.rs.

The results are in the corresponding directories here: https://github.com/BurntSushi/ripgrep/tree/master/benchsuite/runs --- Just about every single benchmark is within one standard deviation of each other, and I didn't see anything close to the perf differences witnessed in the OP.


With that out of the way, this is actually exactly what I expected to see. On average, ripgrep should do almost zero allocations for each file that it searches. Therefore, I wouldn't really call ripgrep an "allocation heavy" workload, so it probably isn't a good benchmark to use for this particular test.

(Actually, I lied when I said I got what I expected. The most interesting thing I learned from this exercise had nothing to do with allocators. What I learned was that MUSL's memchr is seemingly competitive with glibc's memchr. Cool.)

9 Likes