perf: introduce copy-on-write for event system to eliminate all memory reallocations

This commit is contained in:
sxyazi 2024-11-28 01:29:50 +08:00
parent 5e48df5126
commit 1f0817080e
No known key found for this signature in database
8 changed files with 37 additions and 37 deletions

View file

@ -21,7 +21,7 @@ impl<'a> Input<'a> {
bail!("Highlighting is disabled");
}
let (theme, syntaxes) = Highlighter::init();
let (theme, syntaxes) = futures::executor::block_on(Highlighter::init());
if let Some(syntax) = syntaxes.find_syntax_by_name("Bourne Again Shell (bash)") {
let mut h = HighlightLines::new(syntax, theme);
let regions = h.highlight_line(self.cx.input.value(), syntaxes)?;

View file

@ -21,7 +21,7 @@ function M:preload()
return 1
end
local child, err = Command("magick"):args({
local status, err = Command("magick"):args({
"-size",
"800x560",
"-gravity",
@ -37,15 +37,14 @@ function M:preload()
"+0+0",
TEXT,
"JPG:" .. tostring(cache),
}):spawn()
}):status()
if not child then
if status then
return status.success and 1 or 2
else
ya.err("Failed to start `magick`, error: " .. err)
return 0
end
local status = child:wait()
return status and status.success and 1 or 2
end
return M

View file

@ -19,7 +19,7 @@ function M:preload()
return 1
end
local child, err = Command("magick"):args({
local status, err = Command("magick"):args({
"-density",
"200",
tostring(self.file.url),
@ -30,15 +30,14 @@ function M:preload()
tostring(PREVIEW.image_quality),
"-auto-orient",
"JPG:" .. tostring(cache),
}):spawn()
}):status()
if not child then
if status then
return status.success and 1 or 2
else
ya.err("Failed to start `magick`, error: " .. err)
return 0
end
local status = child:wait()
return status and status.success and 1 or 2
end
function M:spot(job) require("file"):spot(job) end

View file

@ -49,7 +49,7 @@ function M:preload()
local ss = math.floor(meta.format.duration * percent / 100)
local qv = 31 - math.floor(PREVIEW.image_quality * 0.3)
-- stylua: ignore
local child, err = Command("ffmpeg"):args({
local status, err = Command("ffmpeg"):args({
"-v", "quiet", "-hwaccel", "auto",
"-skip_frame", "nokey", "-ss", ss,
"-an", "-sn", "-dn",
@ -59,15 +59,14 @@ function M:preload()
"-vf", string.format("scale=%d:-2:flags=fast_bilinear", PREVIEW.max_width),
"-f", "image2",
"-y", tostring(cache),
}):spawn()
}):status()
if not child then
if status then
return status.success and 1 or 2
else
ya.err("Failed to start `ffmpeg`, error: " .. err)
return 0
end
local status = child:wait()
return status and status.success and 1 or 2
end
function M:spot(job)

View file

@ -1,14 +1,14 @@
use std::{borrow::Cow, io::Cursor, mem, path::{Path, PathBuf}, sync::OnceLock};
use std::{borrow::Cow, io::Cursor, mem, path::{Path, PathBuf}};
use anyhow::{Result, anyhow};
use ratatui::{layout::Size, text::{Line, Span, Text}};
use syntect::{LoadingError, dumps, easy::HighlightLines, highlighting::{self, Theme, ThemeSet}, parsing::{SyntaxReference, SyntaxSet}};
use tokio::{fs::File, io::{AsyncBufReadExt, BufReader}};
use tokio::{fs::File, io::{AsyncBufReadExt, BufReader}, sync::OnceCell};
use yazi_config::{PREVIEW, THEME, preview::PreviewWrap};
use yazi_shared::{Ids, errors::PeekError, replace_to_printable};
static INCR: Ids = Ids::new();
static SYNTECT: OnceLock<(Theme, SyntaxSet)> = OnceLock::new();
static SYNTECT: OnceCell<(Theme, SyntaxSet)> = OnceCell::const_new();
pub struct Highlighter {
path: PathBuf,
@ -18,19 +18,22 @@ impl Highlighter {
#[inline]
pub fn new(path: &Path) -> Self { Self { path: path.to_owned() } }
pub fn init() -> (&'static Theme, &'static SyntaxSet) {
let r = SYNTECT.get_or_init(|| {
let theme = std::fs::File::open(&THEME.manager.syntect_theme)
.map_err(LoadingError::Io)
.and_then(|f| ThemeSet::load_from_reader(&mut std::io::BufReader::new(f)))
.or_else(|_| ThemeSet::load_from_reader(&mut Cursor::new(yazi_prebuild::ansi_theme())));
pub async fn init() -> (&'static Theme, &'static SyntaxSet) {
let f = || {
tokio::task::spawn_blocking(|| {
let theme = std::fs::File::open(&THEME.manager.syntect_theme)
.map_err(LoadingError::Io)
.and_then(|f| ThemeSet::load_from_reader(&mut std::io::BufReader::new(f)))
.or_else(|_| ThemeSet::load_from_reader(&mut Cursor::new(yazi_prebuild::ansi_theme())));
let syntaxes = dumps::from_uncompressed_data(yazi_prebuild::syntaxes());
let syntaxes = dumps::from_uncompressed_data(yazi_prebuild::syntaxes());
(theme.unwrap(), syntaxes.unwrap())
});
(theme.unwrap(), syntaxes.unwrap())
})
};
(&r.0, &r.1)
let (theme, syntaxes) = SYNTECT.get_or_try_init(f).await.unwrap();
(theme, syntaxes)
}
#[inline]
@ -100,7 +103,7 @@ impl Highlighter {
syntax: &'static SyntaxReference,
) -> Result<Text<'static>, PeekError> {
let ticket = INCR.current();
let (theme, syntaxes) = Self::init();
let (theme, syntaxes) = Self::init().await;
tokio::task::spawn_blocking(move || {
let mut h = HighlightLines::new(syntax, theme);
@ -128,7 +131,7 @@ impl Highlighter {
}
async fn find_syntax(path: &Path) -> Result<&'static SyntaxReference> {
let (_, syntaxes) = Self::init();
let (_, syntaxes) = Self::init().await;
let name = path.file_name().map(|n| n.to_string_lossy()).unwrap_or_default();
if let Some(s) = syntaxes.find_syntax_by_extension(&name) {
return Ok(s);

View file

@ -2,7 +2,7 @@ use anyhow::bail;
use mlua::{Lua, Table};
use yazi_shared::event::{Cmd, Data};
pub type PluginCallback = Box<dyn FnOnce(&Lua, Table) -> mlua::Result<()> + Send>;
pub type PluginCallback = Box<dyn FnOnce(&Lua, Table) -> mlua::Result<()> + Send + Sync>;
#[derive(Default)]
pub struct PluginOpt {

View file

@ -49,7 +49,7 @@ impl Cmd {
}
#[inline]
pub fn with_any(mut self, name: impl ToString, data: impl Any + Send) -> Self {
pub fn with_any(mut self, name: impl ToString, data: impl Any + Send + Sync) -> Self {
self.args.insert(name.to_string(), Data::Any(Box::new(data)));
self
}

View file

@ -18,7 +18,7 @@ pub enum Data {
#[serde(skip_deserializing)]
Url(Url),
#[serde(skip)]
Any(Box<dyn Any + Send>),
Any(Box<dyn Any + Send + Sync>),
}
impl Data {