perf: use mmap for reading ini config files

This commit is contained in:
Michael Aaron Murphy 2025-04-03 14:26:51 +02:00
parent 09a76900a6
commit 32975f8f05
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
4 changed files with 28 additions and 16 deletions

View file

@ -15,6 +15,7 @@ thiserror = "2.0"
xdg = "2.5"
tracing = "0.1.0"
ini_core = "0.2.0"
memmap2 = "0.9"
[dev-dependencies]
speculoos = "0.11.0"

View file

@ -325,9 +325,15 @@ impl<'a> LookupBuilder<'a> {
let mut parents = icon_themes
.iter()
.flat_map(|t| {
let file = theme::read_ini_theme(&t.index);
let Ok(file) = theme::read_ini_theme(&t.index) else {
return Vec::new();
};
t.inherits(file.as_ref())
let Ok(file) = std::str::from_utf8(file.as_ref()) else {
return Vec::new();
};
t.inherits(file)
.into_iter()
.map(String::from)
.collect::<Vec<String>>()

View file

@ -1,5 +1,6 @@
use crate::theme::error::ThemeError;
use crate::theme::paths::ThemePath;
use memmap2::Mmap;
pub(crate) use paths::BASE_PATHS;
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
@ -15,8 +16,8 @@ type Result<T> = std::result::Result<T, ThemeError>;
pub static THEMES: LazyLock<BTreeMap<String, Vec<Theme>>> = LazyLock::new(get_all_themes);
#[inline]
pub fn read_ini_theme(path: &Path) -> String {
std::fs::read_to_string(path).unwrap_or_default()
pub fn read_ini_theme(path: &Path) -> std::io::Result<Mmap> {
std::fs::File::open(path).and_then(|file| unsafe { Mmap::map(&file) })
}
#[derive(Debug)]
@ -34,10 +35,10 @@ impl Theme {
scale: u16,
force_svg: bool,
) -> Option<PathBuf> {
eprintln!("try_get_icon: {name}");
let file = read_ini_theme(&self.index);
self.try_get_icon_exact_size(file.as_str(), name, size, scale, force_svg)
.or_else(|| self.try_get_icon_closest_size(file.as_str(), name, size, scale, force_svg))
let file = read_ini_theme(&self.index).ok()?;
let file = std::str::from_utf8(file.as_ref()).ok()?;
self.try_get_icon_exact_size(file, name, size, scale, force_svg)
.or_else(|| self.try_get_icon_closest_size(file, name, size, scale, force_svg))
}
#[inline]
@ -234,8 +235,9 @@ mod test {
println!(
"{:?}",
themes.iter().find_map(|t| {
let file = crate::theme::read_ini_theme(&t.index);
t.try_get_icon_exact_size(file.as_str(), "edit-delete-symbolic", 24, 1, false)
let file = super::read_ini_theme(&t.index).ok()?;
let file = std::str::from_utf8(file.as_ref()).ok()?;
t.try_get_icon_exact_size(file, "edit-delete-symbolic", 24, 1, false)
})
);
}
@ -244,8 +246,9 @@ mod test {
fn should_get_png_first() {
let themes = THEMES.get("hicolor").unwrap();
let icon = themes.iter().find_map(|t| {
let file = crate::theme::read_ini_theme(&t.index);
t.try_get_icon_exact_size(file.as_str(), "blueman", 24, 1, true)
let file = super::read_ini_theme(&t.index).ok()?;
let file = std::str::from_utf8(file.as_ref()).ok()?;
t.try_get_icon_exact_size(file, "blueman", 24, 1, true)
});
assert_that!(icon).is_some().is_equal_to(PathBuf::from(
"/usr/share/icons/hicolor/22x22/apps/blueman.png",
@ -256,8 +259,9 @@ mod test {
fn should_get_svg_first() {
let themes = THEMES.get("hicolor").unwrap();
let icon = themes.iter().find_map(|t| {
let file = crate::theme::read_ini_theme(&t.index);
t.try_get_icon_exact_size(file.as_str(), "blueman", 24, 1, false)
let file = super::read_ini_theme(&t.index).ok()?;
let file = std::str::from_utf8(file.as_ref()).ok()?;
t.try_get_icon_exact_size(file, "blueman", 24, 1, false)
});
assert_that!(icon).is_some().is_equal_to(PathBuf::from(
"/usr/share/icons/hicolor/22x22/apps/blueman.png",

View file

@ -127,8 +127,9 @@ mod test {
#[test]
fn should_get_theme_parents() {
for theme in THEMES.get("Arc").unwrap() {
let file = crate::theme::read_ini_theme(&theme.index);
let parents = theme.inherits(&file);
let file = crate::theme::read_ini_theme(&theme.index).ok().unwrap();
let file = std::str::from_utf8(file.as_ref()).ok().unwrap();
let parents = theme.inherits(file);
assert_that!(parents).does_not_contain("hicolor");