diff --git a/CHANGELOG.md b/CHANGELOG.md index 7745ced..bec566e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ ## [Unreleased] - ReleaseDate +### Added + +- Added jemalloc support to fix performace on musl targets + + The global allocator can be switched to jemalloc by enabling the `jemalloc` + cargo feature now. This is not the default because it is not always faster + than the default system allocator; in particular, the glibc allocator has + slightly better performance in multithreaded mode. In addition, jemalloc + uses a bit more memory. + + In addition, the `jemalloc-auto` feature has been introduced, which is enabled + by default and sets the global allocator to jemalloc on platforms where it is + clearly advantageous. For now, this is only done on musl-based targets, as + musl's default allocator is very slow in multithreaded operation (which was + making higher thread counts like `-j8` basically useless due to 7-8x + slowdowns). With the new default, performance on musl is basically identical + to glibc. + + Note that some platforms like `msvc` are unsupported by jemalloc, and trying + to enable the `jemalloc` feature on these platforms may break the MinedMap + build or cause issues at runtime. + ### Changed - Unknown biome types (from not yet supported or modded versions of Minecraft) diff --git a/Cargo.lock b/Cargo.lock index 317eb46..eeaede2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -591,6 +591,7 @@ dependencies = [ "image", "indexmap", "lru", + "minedmap-default-alloc", "minedmap-nbt", "minedmap-resource", "minedmap-types", @@ -608,6 +609,13 @@ dependencies = [ "zstd", ] +[[package]] +name = "minedmap-default-alloc" +version = "0.1.0" +dependencies = [ + "tikv-jemallocator", +] + [[package]] name = "minedmap-nbt" version = "0.1.1" @@ -1057,6 +1065,26 @@ dependencies = [ "once_cell", ] +[[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 = "tokio" version = "1.43.0" diff --git a/Cargo.toml b/Cargo.toml index b821d83..998de6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ git-version = "0.3.5" image = { version = "0.25.1", default-features = false, features = ["png", "webp"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.13.0" +minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.6.0", path = "crates/resource" } minedmap-types = { version = "0.1.4", path = "crates/types" } @@ -64,5 +65,7 @@ tracing-subscriber = "0.3.17" zstd = "0.13.0" [features] -default = ["zlib-ng"] +default = ["jemalloc-auto", "zlib-ng"] +jemalloc-auto = ["dep:minedmap-default-alloc"] +jemalloc = ["jemalloc-auto", "minedmap-default-alloc/jemalloc"] zlib-ng = ["minedmap-nbt/zlib-ng"] diff --git a/crates/default-alloc/Cargo.toml b/crates/default-alloc/Cargo.toml new file mode 100644 index 0000000..40f9e7e --- /dev/null +++ b/crates/default-alloc/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "minedmap-default-alloc" +version = "0.1.0" +description = "Helper crate for target-specific selection of global allocator default" +edition.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true + +[dependencies] +tikv-jemallocator = { version = "0.6.0", optional = true } + +[target.'cfg(target_env = "musl")'.dependencies] +tikv-jemallocator = "*" + +[features] +jemalloc = ["dep:tikv-jemallocator"] diff --git a/crates/default-alloc/src/lib.rs b/crates/default-alloc/src/lib.rs new file mode 100644 index 0000000..0797a5f --- /dev/null +++ b/crates/default-alloc/src/lib.rs @@ -0,0 +1,3 @@ +#[cfg(any(target_env = "musl", feature = "jemalloc"))] +#[global_allocator] +static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; diff --git a/src/main.rs b/src/main.rs index 31f2889..1f19a41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,9 @@ #![warn(missing_docs)] #![warn(clippy::missing_docs_in_private_items)] +#[cfg(feature = "jemalloc-auto")] +extern crate minedmap_default_alloc; + mod core; mod io; mod util;