From 7628f5f51ca209cb3de752dc7ed59bdf6658e63b Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Fri, 13 Jun 2025 00:54:08 +0100 Subject: [PATCH] Switch to jemalloc, at least for now See discussions in #805. --- Cargo.lock | 41 +++++++++++++++++++++-------------------- Cargo.toml | 7 +++---- src/main.rs | 23 +++++++++++++++++++---- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba5ae41a6..6245070aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,10 +254,8 @@ dependencies = [ "ignore", "lazy_static", "libc", - "libmimalloc-sys", "line-numbers", "log", - "mimalloc", "owo-colors", "predicates", "pretty_assertions", @@ -272,6 +270,7 @@ dependencies = [ "streaming-iterator", "strsim 0.10.0", "strum", + "tikv-jemallocator", "tree-sitter", "tree-sitter-bash", "tree-sitter-c", @@ -516,15 +515,6 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" -[[package]] -name = "libmimalloc-sys" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7705fc40f6ed493f73584abbb324e74f96b358ff60dfe5659a0f8fc12c590a69" -dependencies = [ - "cc", -] - [[package]] name = "line-numbers" version = "0.3.0" @@ -559,15 +549,6 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "mimalloc" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dfa131390c2f6bdb3242f65ff271fcdaca5ff7b6c08f28398be7f2280e3926" -dependencies = [ - "libmimalloc-sys", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -983,6 +964,26 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +[[package]] +name = "tikv-jemalloc-sys" +version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + [[package]] name = "tree-sitter" version = "0.24.5" diff --git a/Cargo.toml b/Cargo.toml index 71cdcfc75..6b3a270f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,10 +44,9 @@ libc = "0.2.108" log = "0.4.14" pretty_env_logger = "0.5.0" -mimalloc = { version = "0.1.28", default-features = false } -# Pin libmimalloc-sys due to 0.1.25 producing a huge slowdown in very -# large textual files, as discussed in #297. -libmimalloc-sys = "=0.1.24" +[target.'cfg(not(target_env = "msvc"))'.dependencies] +tikv-jemallocator = "0.6" + radix-heap = "0.4.2" # ignore does not declare a MSRV, but it's part of ripgrep, which has # a slightly more aggressive MSRV than difftastic. Constrain ignore to diff --git a/src/main.rs b/src/main.rs index 7278c084a..1fca0725f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,7 +50,6 @@ extern crate log; use display::style::print_warning; use log::info; -use mimalloc::MiMalloc; use options::FilePermissions; use options::USAGE; @@ -73,10 +72,26 @@ use crate::parse::syntax; /// The global allocator used by difftastic. /// -/// Diffing allocates a large amount of memory, and `MiMalloc` performs -/// better. +/// Diffing allocates a large amount of memory, and both Jemalloc and +/// MiMalloc perform better than the system allocator. +/// +/// Some versions of MiMalloc (specifically libmimalloc-sys greater +/// than 0.1.24) handle very large, mostly unused allocations +/// badly. This makes large line-oriented diffs very slow, as +/// discussed in #297. +/// +/// MiMalloc is generally faster than Jemalloc, but older versions of +/// MiMalloc don't compile on GCC 15+, so use Jemalloc for now. See +/// #805. +/// +/// For reference, Jemalloc uses 10-20% more time (although up to 33% +/// more instructions) when testing on sample files. +#[cfg(not(target_env = "msvc"))] +use tikv_jemallocator::Jemalloc; + +#[cfg(not(target_env = "msvc"))] #[global_allocator] -static GLOBAL: MiMalloc = MiMalloc; +static GLOBAL: Jemalloc = Jemalloc; use std::path::Path; use std::{env, thread};