use std::hint::black_box; use criterion::{BatchSize, Criterion, Throughput, criterion_group, criterion_main}; use quote::quote; criterion_main!(benches); criterion_group!(benches, hello_world, librustdoc); fn extern_crate_askama() -> proc_macro2::TokenStream { quote! { extern crate askama; } } fn hello_world(c: &mut Criterion) { let source = "

Hello, {{user}}!

"; let ts = quote! { #[derive(Template)] #[template( source = #source, ext = "html" )] struct Hello<'a> { user: &'a str, } }; let mut g = c.benchmark_group("synthetic"); g.throughput(Throughput::Bytes(source.len().try_into().unwrap())); g.bench_function("hello_world", |b| { b.iter_batched( || ts.clone(), |ts| askama_derive::derive_template(black_box(ts), extern_crate_askama), BatchSize::LargeInput, ); }); g.finish(); } fn librustdoc(c: &mut Criterion) { let mut g = c.benchmark_group("librustdoc"); macro_rules! benches { ($($name:expr => $struct:item)*) => { $({ const SOURCE: &str = include_str!(concat!("../../askama_parser/benches/librustdoc/", $name)); let ts = quote! { #[derive(Template)] #[template(source = #SOURCE, ext = "html")] $struct }; g.throughput(Throughput::Bytes(SOURCE.len().try_into().unwrap())); g.bench_function($name, |b| { b.iter_batched( || ts.clone(), |input| askama_derive::derive_template(input, extern_crate_askama), BatchSize::LargeInput, ) }); })* }; } benches! { "item_info.html" => struct ItemInfo { items: Vec, } "item_union.html" => struct ItemUnion<'a, 'cx> { cx: RefCell<&'a mut Context<'cx>>, it: &'a clean::Item, s: &'a clean::Union, } "page.html" => struct PageLayout<'a> { static_root_path: String, page: &'a Page<'a>, layout: &'a Layout, files: &'static StaticFiles, themes: Vec, sidebar: String, content: String, rust_channel: &'static str, pub(crate) rustdoc_version: &'a str, display_krate: &'a str, display_krate_with_trailing_slash: String, display_krate_version_number: &'a str, display_krate_version_extra: &'a str, } "print_item.html" => struct ItemVars<'a> { typ: &'a str, name: &'a str, item_type: &'a str, path_components: Vec, stability_since_raw: &'a str, src_href: Option<&'a str>, } "short_item_info.html" => enum ShortItemInfo { /// A message describing the deprecation of this item Deprecation { message: String, }, /// The feature corresponding to an unstable item, and optionally /// a tracking issue URL and number. Unstable { feature: String, tracking: Option<(String, u32)>, }, Portability { message: String, }, } "sidebar.html" => pub(super) struct Sidebar<'a> { pub(super) title_prefix: &'static str, pub(super) title: &'a str, pub(super) is_crate: bool, pub(super) is_mod: bool, pub(super) blocks: Vec>, pub(super) path: String, } "source.html" => struct Source { embedded: bool, needs_expansion: bool, lines: RangeInclusive, code_html: Code, } "type_layout.html" => struct TypeLayout<'cx> { variants: Vec<(Symbol, TypeLayoutSize)>, type_layout_size: Result>, } "type_layout_size.html" => struct TypeLayoutSize { is_unsized: bool, is_uninhabited: bool, size: u64, } } g.finish(); }