From 0fb01fccc3fd9ecbfab3e4febd8668eb0e06bf14 Mon Sep 17 00:00:00 2001 From: Dherse Date: Mon, 14 Jul 2025 14:26:32 +0200 Subject: [PATCH] Replaced `IndexMap` with `EcoVec<(K, V)>` --- Cargo.lock | 2 +- crates/typst-timing/Cargo.toml | 2 +- crates/typst-timing/src/lib.rs | 50 +++++++++++++++++----------------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d41ad244..2e07d04f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3247,7 +3247,7 @@ dependencies = [ name = "typst-timing" version = "0.13.1" dependencies = [ - "indexmap 2.7.1", + "ecow", "parking_lot", "serde", "serde_json", diff --git a/crates/typst-timing/Cargo.toml b/crates/typst-timing/Cargo.toml index dc6035763..6cb805e7b 100644 --- a/crates/typst-timing/Cargo.toml +++ b/crates/typst-timing/Cargo.toml @@ -13,7 +13,7 @@ keywords = { workspace = true } readme = { workspace = true } [dependencies] -indexmap = { workspace = true } +ecow = { workspace = true } parking_lot = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/typst-timing/src/lib.rs b/crates/typst-timing/src/lib.rs index 7adb8c4c1..9f875b558 100644 --- a/crates/typst-timing/src/lib.rs +++ b/crates/typst-timing/src/lib.rs @@ -6,9 +6,8 @@ use std::io::Write; use std::num::NonZeroU64; use std::ops::Not; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use std::sync::Arc; -use indexmap::IndexMap; +use ecow::EcoVec; use parking_lot::Mutex; use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; @@ -106,7 +105,7 @@ pub fn export_json( pid: u64, tid: u64, #[serde(skip_serializing_if = "Option::is_none")] - args: Option, Cow<'a, serde_json::Value>>>, + args: Option, Cow<'a, serde_json::Value>)>>, } let lock = EVENTS.lock(); @@ -118,9 +117,9 @@ pub fn export_json( .map_err(|e| format!("failed to serialize events: {e}"))?; for event in events.iter() { - let mut args = IndexMap::new(); + let mut args = EcoVec::with_capacity(event.arguments.len() * 2 + 1); if let Some(func) = event.func.as_ref() { - args.insert("func".into(), Cow::Owned(serde_json::json!(func))); + args.push(("func".into(), Cow::Owned(serde_json::json!(func)))); } for (key, arg) in event.arguments.iter() { @@ -153,7 +152,7 @@ pub fn export_json( pub struct TimingScope { name: &'static str, func: Option, - args: IndexMap<&'static str, EventArgument>, + args: EcoVec<(&'static str, EventArgument)>, } impl TimingScope { @@ -161,7 +160,7 @@ impl TimingScope { #[inline] pub fn new(name: &'static str) -> Option { if is_enabled() { - Some(Self { name, func: None, args: IndexMap::new() }) + Some(Self { name, func: None, args: EcoVec::new() }) } else { None } @@ -173,17 +172,17 @@ impl TimingScope { } pub fn with_span(mut self, span: NonZeroU64) -> Self { - self.args.insert("span", EventArgument::Span(span)); + self.args.push(("span", EventArgument::Span(span))); self } pub fn with_callsite(mut self, callsite: NonZeroU64) -> Self { - self.args.insert("callsite", EventArgument::Span(callsite)); + self.args.push(("callsite", EventArgument::Span(callsite))); self } pub fn with_named_span(mut self, name: &'static str, span: NonZeroU64) -> Self { - self.args.insert(name, EventArgument::Span(span)); + self.args.push((name, EventArgument::Span(span))); self } @@ -203,7 +202,7 @@ impl TimingScope { value: impl Serialize, ) -> Result { let value = serde_json::to_value(value)?; - self.args.insert(arg, EventArgument::Value(value)); + self.args.push((arg, EventArgument::Value(value))); Ok(self) } @@ -217,7 +216,7 @@ impl TimingScope { name: self.name, func: self.func.clone(), thread_id, - arguments: Arc::new(self.args), + arguments: self.args.clone(), }; EVENTS.lock().push(event.clone()); TimingScopeGuard { scope: Some(event) } @@ -240,6 +239,7 @@ impl Drop for TimingScopeGuard { } } +#[derive(Clone)] enum EventArgument { Span(NonZeroU64), Value(serde_json::Value), @@ -250,45 +250,45 @@ impl EventArgument { &'a self, mut source: impl FnMut(NonZeroU64) -> (String, u32), key: &'static str, - out: &mut IndexMap, Cow<'a, serde_json::Value>>, + out: &mut EcoVec<(Cow<'static, str>, Cow<'a, serde_json::Value>)>, ) -> Result<(), serde_json::Error> { match self { EventArgument::Span(span) => { let (file, line) = source(*span); // Insert file and line information for the span if key == "span" { - out.insert("file".into(), Cow::Owned(serde_json::json!(file))); - out.insert("line".into(), Cow::Owned(serde_json::json!(line))); + out.push(("file".into(), Cow::Owned(serde_json::json!(file)))); + out.push(("line".into(), Cow::Owned(serde_json::json!(line)))); return Ok(()); } // Small optimization for callsite if key == "callsite" { - out.insert( + out.push(( "callsite_file".into(), Cow::Owned(serde_json::json!(file)), - ); - out.insert( + )); + out.push(( "callsite_line".into(), Cow::Owned(serde_json::json!(line)), - ); + )); return Ok(()); } - out.insert( + out.push(( format!("{key}_file").into(), Cow::Owned(serde_json::json!(file)), - ); + )); - out.insert( + out.push(( format!("{key}_line").into(), Cow::Owned(serde_json::json!(line)), - ); + )); } EventArgument::Value(value) => { - out.insert(key.into(), Cow::Borrowed(value)); + out.push((key.into(), Cow::Borrowed(value))); } } @@ -306,7 +306,7 @@ struct Event { /// The name of this event. name: &'static str, /// The additional arguments of this event. - arguments: Arc>, + arguments: EcoVec<(&'static str, EventArgument)>, /// The function being called (if any). func: Option, /// The thread ID of this event.