summaryrefslogtreecommitdiff
path: root/crates/typst-macros
diff options
context:
space:
mode:
authorSébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com>2023-12-30 13:36:15 +0100
committerGitHub <noreply@github.com>2023-12-30 12:36:15 +0000
commitc4d9b0c3d8d2cf895137d2047e597fd3e24e0104 (patch)
tree679241e556928726824262f65b41fcbcb2fbd4a3 /crates/typst-macros
parent4e5afa672f502d53e931d432ec1a36bdc6e16583 (diff)
New performance timings (#3096)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates/typst-macros')
-rw-r--r--crates/typst-macros/src/lib.rs41
-rw-r--r--crates/typst-macros/src/time.rs51
-rw-r--r--crates/typst-macros/src/util.rs1
3 files changed, 93 insertions, 0 deletions
diff --git a/crates/typst-macros/src/lib.rs b/crates/typst-macros/src/lib.rs
index 28d02a6e..8ca7bcac 100644
--- a/crates/typst-macros/src/lib.rs
+++ b/crates/typst-macros/src/lib.rs
@@ -10,6 +10,7 @@ mod elem;
mod func;
mod scope;
mod symbols;
+mod time;
mod ty;
use proc_macro::TokenStream as BoundaryStream;
@@ -342,3 +343,43 @@ pub fn symbols(stream: BoundaryStream) -> BoundaryStream {
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
+
+/// Times the function invokations.
+///
+/// When tracing is enabled in the typst-cli, this macro will record the
+/// invokations of the function and store them in a global map. The map can be
+/// accessed through the `typst_trace::RECORDER` static.
+///
+/// You can also specify the span of the function invokation:
+/// - `#[time(span = ..)]` to record the span, which will be used for the
+/// `EventKey`.
+///
+/// By default, all tracing is ommited using the `wasm32` target flag.
+/// This is done to avoid bloating the web app which doesn't need tracing.
+///
+/// ```ignore
+/// #[time]
+/// fn fibonacci(n: u64) -> u64 {
+/// if n <= 1 {
+/// 1
+/// } else {
+/// fibonacci(n - 1) + fibonacci(n - 2)
+/// }
+/// }
+///
+/// #[time(span = span)]
+/// fn fibonacci_spanned(n: u64, span: Span) -> u64 {
+/// if n <= 1 {
+/// 1
+/// } else {
+/// fibonacci(n - 1) + fibonacci(n - 2)
+/// }
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn time(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream {
+ let item = syn::parse_macro_input!(item as syn::ItemFn);
+ time::time(stream.into(), &item)
+ .unwrap_or_else(|err| err.to_compile_error())
+ .into()
+}
diff --git a/crates/typst-macros/src/time.rs b/crates/typst-macros/src/time.rs
new file mode 100644
index 00000000..fbe1ebc6
--- /dev/null
+++ b/crates/typst-macros/src/time.rs
@@ -0,0 +1,51 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::parse::{Parse, ParseStream};
+use syn::Result;
+
+use crate::util::{kw, parse_key_value, parse_string};
+
+/// Expand the `#[time(..)]` macro.
+pub fn time(stream: TokenStream, item: &syn::ItemFn) -> Result<TokenStream> {
+ let meta: Meta = syn::parse2(stream)?;
+ Ok(create(meta, item))
+}
+
+/// The `..` in `#[time(..)]`.
+pub struct Meta {
+ pub span: Option<syn::Expr>,
+ pub name: Option<String>,
+}
+
+impl Parse for Meta {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Self {
+ name: parse_string::<kw::name>(input)?,
+ span: parse_key_value::<kw::span, syn::Expr>(input)?,
+ })
+ }
+}
+
+fn create(meta: Meta, item: &syn::ItemFn) -> TokenStream {
+ let name = meta.name.unwrap_or_else(|| item.sig.ident.to_string());
+ let span = meta
+ .span
+ .as_ref()
+ .map(|span| quote! { Some(#span) })
+ .unwrap_or_else(|| quote! { None });
+
+ let sig = &item.sig;
+ let vis = &item.vis;
+ let block = &item.block;
+ quote! {
+ #vis #sig {
+ #[cfg(not(target_arch = "wasm32"))]
+ let __scope = ::typst_timing::TimingScope::new(#name, {
+ use ::typst::foundations::NativeElement;
+ #span
+ });
+
+ #block
+ }
+ }
+}
diff --git a/crates/typst-macros/src/util.rs b/crates/typst-macros/src/util.rs
index 32c0aa4e..4f7cc5fb 100644
--- a/crates/typst-macros/src/util.rs
+++ b/crates/typst-macros/src/util.rs
@@ -252,6 +252,7 @@ impl Parse for BareType {
pub mod kw {
syn::custom_keyword!(name);
+ syn::custom_keyword!(span);
syn::custom_keyword!(title);
syn::custom_keyword!(scope);
syn::custom_keyword!(constructor);