use std::collections::HashMap;
use criterion::{criterion_group, criterion_main, Criterion};
use handlebars::Handlebars;
use ramhorns::Content;
use serde::Serialize;
use templet::{Template, Templates};
use valuable::Valuable;
#[derive(Valuable, Content, Serialize)]
struct Page<'a> {
title: &'a str,
products: &'a [Product<'a>],
}
#[derive(Valuable, Content, Serialize)]
struct Item<'a> {
name: &'a str,
}
#[derive(Valuable, Content, Serialize)]
struct Product<'a> {
name: &'a str,
price: Price,
images: &'a [Image<'a>],
}
#[derive(Valuable, Content, Serialize)]
struct Price {
price: i32,
}
#[derive(Valuable, Content, Serialize)]
struct Image<'a> {
title: &'a str,
href: &'a str,
}
pub fn criterion_benchmark(c: &mut Criterion) {
static PAGE: &str = r#"
{{title}}
{{title}}
{{#product}}
-
{{name}}
{{#price}}
Price: {{price}}e
{{/price}}
{{#images}}
{{/images}}
{{/product}}
"#;
static PAGE_HANDLEBARS: &str = r#"
{{title}}
{{title}}
{{#each product}}
-
{{name}}
{{#with price}}
Price: {{price}}e
{{/with}}
{{#each images}}
{{/each}}
{{/each}}
"#;
c.bench_function("parse", |b| {
let mut template = None;
b.iter(|| {
template = Some(Template::parse(PAGE.to_string()));
});
});
c.bench_function("parse_ramhorns", |b| {
let mut template = None;
b.iter(|| {
template = ramhorns::Template::new(PAGE.to_string()).ok();
});
});
c.bench_function("parse_handlebars", |b| {
let mut template = None;
b.iter(|| {
template = Some(handlebars::Template::compile(&PAGE_HANDLEBARS.to_string()).unwrap());
});
});
c.bench_function("render", |b| {
let t = Template::parse(PAGE.to_string());
let mut map = HashMap::new();
map.insert("template".to_owned(), t);
let templates = Templates::new(map);
let mut buf = Vec::new();
let ctx = &Page {
title: "Weird store",
products: &[
Product {
name: "Netflix subscription",
images: &[Image {
title: "Netflix",
href: "/netflix.logo.svg",
}],
price: Price { price: 13 },
},
Product {
name: "Artisan Bread",
images: &[Image {
title: "Bread",
href: "/bread.jpg",
}],
price: Price { price: 4 },
},
Product {
name: "Orange juice",
images: &[Image {
title: "Orange juice",
href: "/orange-juice.jpg",
}],
price: Price { price: 4 },
},
],
};
b.iter(|| {
templates.render("template", &mut buf, &ctx).unwrap();
buf.clear();
})
});
c.bench_function("render_ramhorns", |b| {
let template = ramhorns::Template::new(PAGE).unwrap();
let mut buf = Vec::new();
let ctx = &Page {
title: "Weird store",
products: &[
Product {
name: "Netflix subscription",
images: &[Image {
title: "Netflix",
href: "/netflix.logo.svg",
}],
price: Price { price: 13 },
},
Product {
name: "Artisan Bread",
images: &[Image {
title: "Bread",
href: "/bread.jpg",
}],
price: Price { price: 4 },
},
Product {
name: "Orange juice",
images: &[Image {
title: "Orange juice",
href: "/orange-juice.jpg",
}],
price: Price { price: 4 },
},
],
};
b.iter(|| {
template.render_to_writer(&mut buf, ctx).unwrap();
buf.clear();
});
});
c.bench_function("render_handlebars", |b| {
let mut buf = Vec::new();
let template = handlebars::Template::compile(PAGE_HANDLEBARS).unwrap();
let mut reg = Handlebars::new();
reg.register_template("template", template);
let ctx = &Page {
title: "Weird store",
products: &[
Product {
name: "Netflix subscription",
images: &[Image {
title: "Netflix",
href: "/netflix.logo.svg",
}],
price: Price { price: 13 },
},
Product {
name: "Artisan Bread",
images: &[Image {
title: "Bread",
href: "/bread.jpg",
}],
price: Price { price: 4 },
},
Product {
name: "Orange juice",
images: &[Image {
title: "Orange juice",
href: "/orange-juice.jpg",
}],
price: Price { price: 4 },
},
],
};
b.iter(|| {
reg.render_to_write("template", ctx, &mut buf).unwrap();
buf.clear();
});
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);