From 0752b53298ddcf57fb2ddc289719adcd1564e256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20misaki=20masa?= Date: Wed, 11 Jun 2025 08:49:05 +0800 Subject: [PATCH] perf: sequence-based rendering merge strategy (#2861) --- Cargo.lock | 128 ++++++++++++++++++++++++++++------------ Cargo.toml | 4 +- yazi-boot/Cargo.toml | 4 +- yazi-cli/Cargo.toml | 4 +- yazi-codegen/Cargo.toml | 2 +- yazi-fm/src/app/app.rs | 58 ++++++++++++------ 6 files changed, 136 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4278fb47..9a39f219 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" @@ -28,9 +28,12 @@ dependencies = [ [[package]] name = "aligned-vec" -version = "0.5.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", +] [[package]] name = "allocator-api2" @@ -367,9 +370,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "chrono" @@ -385,9 +388,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.39" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -395,9 +398,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.39" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -407,9 +410,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.52" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a554639e42d0c838336fc4fbedb9e2df3ad1fa4acda149f9126b4ccfcd7900f" +checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677" dependencies = [ "clap", ] @@ -426,9 +429,9 @@ dependencies = [ [[package]] name = "clap_complete_nushell" -version = "4.5.6" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9801fe85d7986742027c6d365728a6a4ecb6d2b09866de18be836fef7ebf7df1" +checksum = "cdb8335b398d197fb3176efe9400c6c053a41733c26794316c73423d212b2f3d" dependencies = [ "clap", "clap_complete", @@ -436,9 +439,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", @@ -448,9 +451,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "clipboard-win" @@ -762,6 +765,26 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1126,9 +1149,9 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" +checksum = "14d75c7014ddab93c232bc6bb9f64790d3dfd1d605199acd4b40b6d69e691e9f" dependencies = [ "byteorder-lite", "quick-error", @@ -1431,9 +1454,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", "simd-adler32", @@ -1976,8 +1999,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -1987,7 +2020,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -1999,6 +2042,15 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + [[package]] name = "ratatui" version = "0.29.0" @@ -2046,8 +2098,8 @@ dependencies = [ "once_cell", "paste", "profiling", - "rand", - "rand_chacha", + "rand 0.8.5", + "rand_chacha 0.3.1", "simd_helpers", "system-deps", "thiserror 1.0.69", @@ -2151,9 +2203,9 @@ checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -2434,9 +2486,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.101" +version = "2.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "f6397daf94fa90f058bd0fd88429dd9e5738999cca8d701813c80723add80462" dependencies = [ "proc-macro2", "quote", @@ -2790,11 +2842,11 @@ dependencies = [ [[package]] name = "twox-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7b17f197b3050ba473acf9181f7b1d3b66d1cf7356c6cc57886662276e65908" +checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56" dependencies = [ - "rand", + "rand 0.9.1", ] [[package]] @@ -2868,9 +2920,9 @@ dependencies = [ [[package]] name = "v_frame" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2" dependencies = [ "aligned-vec", "num-traits", @@ -3708,9 +3760,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4a518c0ea2576f4da876349d7f67a7be489297cd77c2cf9e04c2e05fcd3974" +checksum = "0f6fe2e33d02a98ee64423802e16df3de99c43e5cf5ff983767e1128b394c8ac" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index f12376b6..b21c226d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ ansi-to-tui = "7.0.0" anyhow = "1.0.98" base64 = "0.22.1" bitflags = "2.9.1" -clap = { version = "4.5.39", features = [ "derive" ] } +clap = { version = "4.5.40", features = [ "derive" ] } core-foundation-sys = "0.8.7" crossterm = { version = "0.29.0", features = [ "event-stream" ] } dirs = "6.0.0" @@ -49,6 +49,6 @@ tokio-stream = "0.1.17" tokio-util = "0.7.15" toml = { version = "0.8.23" } tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] } -twox-hash = { version = "2.1.0", default-features = false, features = [ "std", "random", "xxhash3_128" ] } +twox-hash = { version = "2.1.1", default-features = false, features = [ "std", "random", "xxhash3_128" ] } unicode-width = { version = "0.2.0", default-features = false } uzers = "0.12.1" diff --git a/yazi-boot/Cargo.toml b/yazi-boot/Cargo.toml index 5a1376c1..b8d02367 100644 --- a/yazi-boot/Cargo.toml +++ b/yazi-boot/Cargo.toml @@ -25,7 +25,7 @@ yazi-shared = { path = "../yazi-shared", version = "25.5.31" } # External dependencies clap = { workspace = true } -clap_complete = "4.5.52" +clap_complete = "4.5.54" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.6" +clap_complete_nushell = "4.5.7" vergen-gitcl = { version = "1.0.8", features = [ "build", "rustc" ] } diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index 1ad12ae9..248ed1dc 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -31,9 +31,9 @@ yazi-shared = { path = "../yazi-shared", version = "25.5.31" } # External build dependencies anyhow = { workspace = true } clap = { workspace = true } -clap_complete = "4.5.52" +clap_complete = "4.5.54" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.6" +clap_complete_nushell = "4.5.7" serde_json = { workspace = true } vergen-gitcl = { version = "1.0.8", features = [ "build" ] } diff --git a/yazi-codegen/Cargo.toml b/yazi-codegen/Cargo.toml index eecdfa2b..a02b35db 100644 --- a/yazi-codegen/Cargo.toml +++ b/yazi-codegen/Cargo.toml @@ -13,5 +13,5 @@ proc-macro = true [dependencies] # External dependencies -syn = { version = "2.0.101", features = [ "full" ] } +syn = { version = "2.0.102", features = [ "full" ] } quote = "1.0.40" diff --git a/yazi-fm/src/app/app.rs b/yazi-fm/src/app/app.rs index 8491c473..e97fd239 100644 --- a/yazi-fm/src/app/app.rs +++ b/yazi-fm/src/app/app.rs @@ -1,7 +1,8 @@ -use std::sync::atomic::Ordering; +use std::{sync::atomic::Ordering, time::{Duration, Instant}}; use anyhow::Result; use crossterm::event::KeyEvent; +use tokio::{select, time::sleep}; use yazi_config::keymap::Key; use yazi_macro::emit; use yazi_shared::event::{CmdCow, Event, NEED_RENDER}; @@ -23,27 +24,46 @@ impl App { let mut app = Self { cx: Ctx::make(), term: Some(term), signals }; app.render(); - let mut times = 0; - let mut events = Vec::with_capacity(200); - while rx.recv_many(&mut events, 50).await > 0 { - for event in events.drain(..) { - times += 1; - app.dispatch(event)?; - } + let mut events = Vec::with_capacity(50); + macro_rules! drain_events { + () => { + for event in events.drain(..) { + app.dispatch(event)?; + try_render!(); + } + }; + } - if !NEED_RENDER.swap(false, Ordering::Relaxed) { - continue; - } + let (mut timeout, mut last_render) = (None, Instant::now()); + macro_rules! try_render { + () => { + if NEED_RENDER.load(Ordering::Relaxed) { + if let Some(sub) = Duration::from_millis(10).checked_sub(last_render.elapsed()) { + timeout = Some(sleep(sub)); + } else { + app.render(); + (timeout, last_render) = (None, Instant::now()); + } + } + }; + } - if times >= 50 { - times = 0; - app.render(); - } else if let Ok(event) = rx.try_recv() { - events.push(event); - emit!(Render); + loop { + if let Some(t) = timeout.take() { + select! { + _ = t => { + app.render(); + last_render = Instant::now(); + } + n = rx.recv_many(&mut events, 50) => { + if n == 0 { break } + drain_events!(); + } + } + } else if rx.recv_many(&mut events, 50).await > 0 { + drain_events!(); } else { - times = 0; - app.render(); + break; } } Ok(())