Benchmark alokatorów na prostym budowaniu wektora
fn main() { let mut v = vec![]; let time = Instant::now(); for i in 0..100_000_000 { let mut s = String::new(); itoa::fmt(&mut s, i).unwrap(); v.push(s); } }
A teraz wyniki
Systemowy alokator
[nerull@anvil alloc-bench]$ time ./target/release/alloc-bench real 0m4,813s user 0m3,665s sys 0m1,148s [nerull@anvil alloc-bench]$
Wyniki profilowania za pomocą perf
perf record --call-graph dwarf -g -- ./target/release/alloc-bench
podgląd można zobaczyć za pomocą komendy
perf report -G
TcMalloc
[nerull@anvil alloc-bench]$ time ./target/release/alloc-bench tcmalloc: large alloc 1610612736 bytes == 0x55a92111c000 @ 0x7fd18e796d0d 0x7fd18e7b7e8c 0x55a8c01e3595 0x55a8c01e3690 0x55a8c01e3772 0x55a8c01e3404 0x55a8c01e3656 0x55a8c01e316c 0x55a8c01fd487 0x55a8c01e3645 0x7fd18e57ccb2 0x55a8c01e309e tcmalloc: large alloc 3221225472 bytes == 0x55a98191c000 @ 0x7fd18e796d0d 0x7fd18e7b7e8c 0x55a8c01e3595 0x55a8c01e3690 0x55a8c01e3772 0x55a8c01e3404 0x55a8c01e3656 0x55a8c01e316c 0x55a8c01fd487 0x55a8c01e3645 0x7fd18e57ccb2 0x55a8c01e309e real 0m4,734s user 0m3,462s sys 0m1,271s [nerull@anvil alloc-bench]$
Wyniki profilowania
MiMalloc
[nerull@anvil alloc-bench]$ time ./target/release/alloc-bench real 0m3,917s user 0m2,568s sys 0m1,348s [nerull@anvil alloc-bench]$
Wyniki profilowania
Jak widać Microsoftowy alokator pamięci wychodzi najlepiej ze wszystkich alokatorów. Śmiało mogę potwierdzić wyniki benchmarków od MS: https://github.com/microsoft/mimalloc#performance
Użycie mimalloc w Rust: https://crates.io/crates/mimalloc
Dodatkowo możemy sobie dodać flagę, która optymalizuje kompilator LLVM:
RUSTFLAGS="--emit=llvm-ir"
Wynik testu: mimalloc + flagi
[nerull@anvil alloc-bench]$ time ./target/release/alloc-bench real 0m3,717s user 0m2,388s sys 0m1,328s [nerull@anvil alloc-bench]$
Dużym plusem mimalloca jest to, że nie ma żadnych dodatkowych zależności do zewnętrznych bibliotek jak tcmalloc i działa np z klientem oracle
[nerull@anvil alloc-bench]$ ldd ./target/release/alloc-bench linux-vdso.so.1 (0x00007fff3d9e4000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc47d189000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc47d167000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc47d161000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc47cf77000) /lib64/ld-linux-x86-64.so.2 (0x00007fc47d235000) [nerull@anvil alloc-bench]$