perf: switch memory allocator to mimalloc (#4083)

This commit is contained in:
三咲雅 misaki masa 2026-06-26 14:34:28 +08:00 committed by GitHub
parent ef654f4420
commit de611b0e6b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 141 additions and 75 deletions

View file

@ -1,16 +1,5 @@
[env] [env]
MACOSX_DEPLOYMENT_TARGET = "10.12" MACOSX_DEPLOYMENT_TARGET = "10.12"
JEMALLOC_SYS_WITH_LG_PAGE = "16"
# environment variable for tikv-jemalloc-sys
#
# https://jemalloc.net/jemalloc.3.html#opt.narenas
# narenas is the maximum number of arenas to use for automatic multiplexing
# of threads and arenas. The default is four times the number of CPUs,
# or one if there is a single CPU.
#
# Improve memory efficiency by reducing fragmentation and ensuring all threads allocate from the same pool
JEMALLOC_SYS_WITH_MALLOC_CONF = "narenas:1"
[target.aarch64-apple-darwin] [target.aarch64-apple-darwin]
rustflags = [ "-Ctarget-cpu=apple-m1" ] rustflags = [ "-Ctarget-cpu=apple-m1" ]

86
Cargo.lock generated
View file

@ -161,9 +161,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.102" version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
[[package]] [[package]]
name = "approx" name = "approx"
@ -459,12 +459,12 @@ dependencies = [
[[package]] [[package]]
name = "bstr" name = "bstr"
version = "1.12.1" version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79"
dependencies = [ dependencies = [
"memchr", "memchr",
"serde", "serde_core",
] ]
[[package]] [[package]]
@ -1802,9 +1802,9 @@ dependencies = [
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.102" version = "0.3.103"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"futures-util", "futures-util",
@ -1896,6 +1896,15 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libmimalloc-sys"
version = "0.1.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "libredox" name = "libredox"
version = "0.1.17" version = "0.1.17"
@ -2011,6 +2020,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "mimalloc"
version = "0.1.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862"
dependencies = [
"libmimalloc-sys",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.9" version = "0.8.9"
@ -3809,26 +3827,6 @@ dependencies = [
"zune-jpeg", "zune-jpeg",
] ]
[[package]]
name = "tikv-jemalloc-sys"
version = "0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd8aa5b2ab86a2cefa406d889139c162cbb230092f7d1d7cbc1716405d852a3b"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "tikv-jemallocator"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0359b4327f954e0567e69fb191cf1436617748813819c94b8cd4a431422d053a"
dependencies = [
"libc",
"tikv-jemalloc-sys",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.51" version = "0.3.51"
@ -4183,9 +4181,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]] [[package]]
name = "vergen" name = "vergen"
version = "10.0.0" version = "10.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bdf18a54cf91b4d98a8e8b67f6321606539fbcdcac02536286ad1de37b53fd2" checksum = "b5574dd2f922b1a46a06a4b1dc11193a4012108fd54cf725e1816cb8183d8778"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bon", "bon",
@ -4197,9 +4195,9 @@ dependencies = [
[[package]] [[package]]
name = "vergen-gitcl" name = "vergen-gitcl"
version = "10.0.0" version = "10.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4961429ed12888cb3c6dd20f7dc9508c821091a3ba5fec0156ed5a654c1c4572" checksum = "23d9fead6d7c515ac3a658e1a65d36925525d5cfdea414e27eb99b99ffd92bfa"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bon", "bon",
@ -4211,9 +4209,9 @@ dependencies = [
[[package]] [[package]]
name = "vergen-lib" name = "vergen-lib"
version = "10.0.0" version = "10.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "910e8471e27130bbc019e9bfa6bda16dfc4c6dd7c5d0793da70a9256caeae984" checksum = "8cd42fd155c2c2971f6d00face12ec245fbb604fce011ccaf2306d014c2e97ca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bon", "bon",
@ -4253,9 +4251,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.125" version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
@ -4266,9 +4264,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.75" version = "0.4.76"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@ -4276,9 +4274,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.125" version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -4286,9 +4284,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.125" version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
@ -4299,9 +4297,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.125" version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -4980,12 +4978,12 @@ dependencies = [
"better-panic", "better-panic",
"fdlimit", "fdlimit",
"libc", "libc",
"mimalloc",
"mlua", "mlua",
"paste", "paste",
"ratatui-core", "ratatui-core",
"ratatui-widgets", "ratatui-widgets",
"signal-hook-tokio", "signal-hook-tokio",
"tikv-jemallocator",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tracing", "tracing",

View file

@ -36,7 +36,7 @@ debug = false
[workspace.dependencies] [workspace.dependencies]
ansi-to-tui = "8.0.1" ansi-to-tui = "8.0.1"
anyhow = "1.0.102" anyhow = "1.0.103"
arc-swap = { version = "1.9.1", features = [ "serde" ] } arc-swap = { version = "1.9.1", features = [ "serde" ] }
base64 = "0.22.1" base64 = "0.22.1"
bitflags = { version = "2.13.0", features = [ "serde" ] } bitflags = { version = "2.13.0", features = [ "serde" ] }

View file

@ -7,7 +7,6 @@
installShellFiles, installShellFiles,
fetchFromGitHub, fetchFromGitHub,
rust-jemalloc-sys,
imagemagick, imagemagick,
}: }:
@ -41,10 +40,6 @@ rustPlatform.buildRustPackage (finalAttrs: {
imagemagick imagemagick
]; ];
buildInputs = [
rust-jemalloc-sys
];
postInstall = '' postInstall = ''
installShellCompletion --cmd yazi \ installShellCompletion --cmd yazi \
--bash ./yazi-boot/completions/yazi.bash \ --bash ./yazi-boot/completions/yazi.bash \

View file

@ -4,6 +4,7 @@ yazi_macro::mod_flat!(icon inject layout mixing pattern platform preset priority
use std::io::{Read, Write}; use std::io::{Read, Write};
use yazi_macro::writef;
use yazi_shim::{cell::{RoCell, SyncCell}, toml::{DeserializeOver, DeserializeOverWith}}; use yazi_shim::{cell::{RoCell, SyncCell}, toml::{DeserializeOver, DeserializeOverWith}};
use yazi_tty::{TTY, sequence::SetSgr}; use yazi_tty::{TTY, sequence::SetSgr};
@ -67,14 +68,14 @@ pub fn build_flavor(light: bool, merge: bool) -> anyhow::Result<theme::Theme> {
} }
fn wait_for_key(e: anyhow::Error) -> anyhow::Result<()> { fn wait_for_key(e: anyhow::Error) -> anyhow::Result<()> {
let stdout = &mut *TTY.lockout(); let mut stdout = &mut *TTY.lockout();
writeln!(stdout, "{e}")?; writeln!(stdout, "{e}")?;
if let Some(src) = e.source() { if let Some(src) = e.source() {
writeln!(stdout, "\nCaused by:\n{src}")?; writeln!(stdout, "\nCaused by:\n{src}")?;
} }
writeln!( writef!(
stdout, stdout,
"{}{}Press <Enter> to continue with preset settings...{}", "{}{}Press <Enter> to continue with preset settings...{}",
SetSgr::Reverse, SetSgr::Reverse,

View file

@ -1,5 +1,7 @@
use anyhow::bail; use anyhow::bail;
use mlua::{ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use yazi_binding::deprecate;
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(try_from = "[u16; 3]")] #[serde(try_from = "[u16; 3]")]
@ -29,3 +31,83 @@ impl TryFrom<[u16; 3]> for MgrRatio {
}) })
} }
} }
// TODO: remove ---
impl MgrRatio {
fn at(self, idx: usize) -> Option<u16> {
match idx {
0 => Some(self.parent),
1 => Some(self.current),
2 => Some(self.preview),
_ => None,
}
}
}
impl FromLua for MgrRatio {
fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> {
match value {
Value::UserData(ud) => Ok(*ud.borrow::<Self>()?),
Value::Table(t) => from_table(&t, lua),
_ => Err("expected a table".into_lua_err()),
}
}
}
fn from_table(t: &Table, lua: &Lua) -> mlua::Result<MgrRatio> {
if t.contains_key("parent")? || t.contains_key("current")? || t.contains_key("preview")? {
deprecate!(
lua,
"{}: the table form of `rt.mgr.ratio` is deprecated, use an array `[parent, current, preview]` instead"
);
MgrRatio::try_from([t.get("parent")?, t.get("current")?, t.get("preview")?])
.map_err(|e| e.into_lua_err())
} else {
MgrRatio::try_from([t.get(1)?, t.get(2)?, t.get(3)?]).map_err(|e| e.into_lua_err())
}
}
impl UserData for MgrRatio {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::Len, |_, _, ()| Ok(3usize));
methods.add_meta_method(MetaMethod::Index, |lua, me, key: Value| {
match key {
Value::Integer(i) if (1..=3).contains(&i) => me.at((i - 1) as usize).into_lua(lua),
Value::String(s) => match &*s.as_bytes() {
b"parent" => {
deprecate!(
lua,
"{}: `rt.mgr.ratio.parent` is deprecated, use `rt.mgr.ratio[1]` instead"
);
me.parent.into_lua(lua)
}
b"current" => {
deprecate!(
lua,
"{}: `rt.mgr.ratio.current` is deprecated, use `rt.mgr.ratio[2]` instead"
);
me.current.into_lua(lua)
}
b"preview" => {
deprecate!(
lua,
"{}: `rt.mgr.ratio.preview` is deprecated, use `rt.mgr.ratio[3]` instead"
);
me.preview.into_lua(lua)
}
b"all" => {
deprecate!(
lua,
"{}: `rt.mgr.ratio.all` is deprecated, use `rt.mgr.ratio[1] + rt.mgr.ratio[2] + rt.mgr.ratio[3]` instead"
);
me.all.into_lua(lua)
}
_ => Ok(Value::Nil),
},
_ => Ok(Value::Nil),
}
});
}
}
// --- TODO: remove

View file

@ -59,7 +59,7 @@ libc = { workspace = true }
signal-hook-tokio = { version = "0.4.0", features = [ "futures-v0_3" ] } signal-hook-tokio = { version = "0.4.0", features = [ "futures-v0_3" ] }
[target.'cfg(all(not(target_os = "macos"), not(target_os = "windows")))'.dependencies] [target.'cfg(all(not(target_os = "macos"), not(target_os = "windows")))'.dependencies]
tikv-jemallocator = "0.6.1" mimalloc = "0.1.52"
[[bin]] [[bin]]
name = "yazi" name = "yazi"

View file

@ -1,6 +1,6 @@
#[cfg(all(not(target_os = "macos"), not(target_os = "windows")))] #[cfg(all(not(target_os = "macos"), not(target_os = "windows")))]
#[global_allocator] #[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
yazi_macro::mod_pub!(app cmp confirm help input mgr notify pick spot tasks which); yazi_macro::mod_pub!(app cmp confirm help input mgr notify pick spot tasks which);

View file

@ -42,7 +42,7 @@ function Rail:drag(event)
end end
local r = rt.mgr.ratio local r = rt.mgr.ratio
if r.parent ~= parent or r.current ~= current or r.preview ~= preview then if r[1] ~= parent or r[2] ~= current or r[3] ~= preview then
rt.mgr.ratio = { parent, current, preview } rt.mgr.ratio = { parent, current, preview }
ui.render() ui.render()
end end

View file

@ -11,12 +11,13 @@ end
function Tab:layout() function Tab:layout()
local ratio = rt.mgr.ratio local ratio = rt.mgr.ratio
local all = ratio[1] + ratio[2] + ratio[3]
self._chunks = ui.Layout() self._chunks = ui.Layout()
:direction(ui.Layout.HORIZONTAL) :direction(ui.Layout.HORIZONTAL)
:constraints({ :constraints({
ui.Constraint.Ratio(ratio.parent, ratio.all), ui.Constraint.Ratio(ratio[1], all),
ui.Constraint.Ratio(ratio.current, ratio.all), ui.Constraint.Ratio(ratio[2], all),
ui.Constraint.Ratio(ratio.preview, ratio.all), ui.Constraint.Ratio(ratio[3], all),
}) })
:split(self._area) :split(self._area)
end end

View file

@ -1,7 +1,7 @@
use mlua::{IntoLua, Lua, LuaSerdeExt, Value}; use mlua::{FromLua, IntoLua, Lua, LuaSerdeExt, Value};
use yazi_binding::{Composer, ComposerGet, ComposerSet, elements::Wrap}; use yazi_binding::{Composer, ComposerGet, ComposerSet, elements::Wrap};
use yazi_boot::ARGS; use yazi_boot::ARGS;
use yazi_config::YAZI; use yazi_config::{YAZI, mgr::MgrRatio};
use yazi_shared::url::UrlBuf; use yazi_shared::url::UrlBuf;
use yazi_shim::mlua::SER_OPT; use yazi_shim::mlua::SER_OPT;
use yazi_tty::TTY; use yazi_tty::TTY;
@ -60,7 +60,7 @@ fn mgr() -> Composer<ComposerGet, ComposerSet> {
fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> { fn get(lua: &Lua, key: &[u8]) -> mlua::Result<Value> {
let m = &YAZI.mgr; let m = &YAZI.mgr;
match key { match key {
b"ratio" => lua.to_value_with(&m.ratio, SER_OPT)?, b"ratio" => m.ratio.get().into_lua(lua)?,
b"sort_by" => lua.to_value_with(&m.sort_by, SER_OPT)?, b"sort_by" => lua.to_value_with(&m.sort_by, SER_OPT)?,
b"sort_sensitive" => m.sort_sensitive.get().into_lua(lua)?, b"sort_sensitive" => m.sort_sensitive.get().into_lua(lua)?,
@ -83,7 +83,7 @@ fn mgr() -> Composer<ComposerGet, ComposerSet> {
let m = &YAZI.mgr; let m = &YAZI.mgr;
Ok(match key { Ok(match key {
b"ratio" => { b"ratio" => {
m.ratio.set(lua.from_value(value)?); m.ratio.set(MgrRatio::from_lua(value, lua)?);
Value::Nil Value::Nil
} }
_ => value, _ => value,

View file

@ -13,4 +13,4 @@ rust-version.workspace = true
workspace = true workspace = true
[build-dependencies] [build-dependencies]
vergen-gitcl = { version = "10.0.0", features = [ "build", "rustc" ] } vergen-gitcl = { version = "10.0.1", features = [ "build", "rustc" ] }