]> git.proxmox.com Git - rustc.git/blame - vendor/handlebars/benches/bench.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / vendor / handlebars / benches / bench.rs
CommitLineData
f9f354fc
XL
1#[macro_use]
2extern crate criterion;
ea8adc8c
XL
3#[macro_use]
4extern crate serde_derive;
8bb4bdeb 5
94222f64
XL
6use criterion::Criterion;
7use handlebars::{to_json, Context, Handlebars, Template};
8use serde_json::value::Value as Json;
8bb4bdeb
XL
9use std::collections::BTreeMap;
10
94222f64 11#[cfg(unix)]
f9f354fc 12use criterion::profiler::Profiler;
94222f64 13#[cfg(unix)]
3dfed10e 14use pprof::protos::Message;
94222f64 15#[cfg(unix)]
3dfed10e 16use pprof::ProfilerGuard;
8bb4bdeb 17
94222f64
XL
18#[cfg(unix)]
19use std::fs::{create_dir_all, File};
20#[cfg(unix)]
21use std::io::Write;
22#[cfg(unix)]
23use std::path::Path;
24
25#[cfg(unix)]
3dfed10e
XL
26#[derive(Default)]
27struct CpuProfiler<'a> {
28 guard: Option<ProfilerGuard<'a>>,
29}
f9f354fc 30
94222f64 31#[cfg(unix)]
3dfed10e
XL
32impl<'a> Profiler for CpuProfiler<'a> {
33 fn start_profiling(&mut self, _benchmark_id: &str, benchmark_dir: &Path) {
f9f354fc 34 create_dir_all(&benchmark_dir).unwrap();
3dfed10e
XL
35
36 let guard = ProfilerGuard::new(100).unwrap();
37 self.guard = Some(guard);
f9f354fc
XL
38 }
39
3dfed10e
XL
40 fn stop_profiling(&mut self, benchmark_id: &str, benchmark_dir: &Path) {
41 if let Ok(ref report) = self.guard.as_ref().unwrap().report().build() {
42 let fg_file_name = benchmark_dir.join(format!("{}.svg", benchmark_id));
43 let fg_file = File::create(fg_file_name).unwrap();
44 report.flamegraph(fg_file).unwrap();
45
46 let pb_file_name = benchmark_dir.join(format!("{}.pb", benchmark_id));
47 let mut pb_file = File::create(pb_file_name).unwrap();
48 let profile = report.pprof().unwrap();
49
50 let mut content = Vec::new();
51 profile.encode(&mut content).unwrap();
52 pb_file.write_all(&content).unwrap();
53 };
54
55 self.guard = None;
f9f354fc
XL
56 }
57}
58
94222f64 59#[cfg(unix)]
f9f354fc 60fn profiled() -> Criterion {
3dfed10e 61 Criterion::default().with_profiler(CpuProfiler::default())
f9f354fc
XL
62}
63
64#[derive(Serialize)]
65struct DataWrapper {
66 v: String,
67}
68
69#[derive(Serialize)]
70struct RowWrapper {
71 real: Vec<DataWrapper>,
72 dummy: Vec<DataWrapper>,
73}
74
75#[derive(Serialize)]
76struct NestedRowWrapper {
77 parent: Vec<Vec<DataWrapper>>,
78}
79
8bb4bdeb
XL
80static SOURCE: &'static str = "<html>
81 <head>
82 <title>{{year}}</title>
83 </head>
84 <body>
85 <h1>CSL {{year}}</h1>
86 <ul>
87 {{#each teams}}
88 <li class=\"{{#if @first}}champion{{/if}}\">
89 <b>{{name}}</b>: {{score}}
90 </li>
91 {{/each}}
92 </ul>
93 </body>
94</html>";
95
96fn make_data() -> BTreeMap<String, Json> {
97 let mut data = BTreeMap::new();
98
9fa01778 99 data.insert("year".to_string(), to_json("2015"));
8bb4bdeb
XL
100
101 let mut teams = Vec::new();
102
ea8adc8c
XL
103 for v in vec![
104 ("Jiangsu", 43u16),
105 ("Beijing", 27u16),
106 ("Guangzhou", 22u16),
107 ("Shandong", 12u16),
416331ca
XL
108 ]
109 .iter()
ea8adc8c 110 {
8bb4bdeb
XL
111 let (name, score) = *v;
112 let mut t = BTreeMap::new();
9fa01778
XL
113 t.insert("name".to_string(), to_json(name));
114 t.insert("score".to_string(), to_json(score));
8bb4bdeb
XL
115 teams.push(t)
116 }
117
041b39d2 118 data.insert("teams".to_string(), to_json(&teams));
8bb4bdeb
XL
119 data
120}
121
f9f354fc
XL
122fn parse_template(c: &mut Criterion) {
123 c.bench_function("parse_template", move |b| {
124 b.iter(|| Template::compile(SOURCE).ok().unwrap())
125 });
8bb4bdeb
XL
126}
127
f9f354fc 128fn render_template(c: &mut Criterion) {
8bb4bdeb 129 let mut handlebars = Handlebars::new();
ea8adc8c
XL
130 handlebars
131 .register_template_string("table", SOURCE)
132 .ok()
133 .expect("Invalid template format");
8bb4bdeb 134
3dfed10e 135 let ctx = Context::wraps(make_data()).unwrap();
f9f354fc 136 c.bench_function("render_template", move |b| {
3dfed10e 137 b.iter(|| handlebars.render_with_context("table", &ctx).ok().unwrap())
f9f354fc 138 });
8bb4bdeb 139}
ea8adc8c 140
f9f354fc 141fn large_loop_helper(c: &mut Criterion) {
ea8adc8c
XL
142 let mut handlebars = Handlebars::new();
143 handlebars
144 .register_template_string("test", "BEFORE\n{{#each real}}{{this.v}}{{/each}}AFTER")
145 .ok()
146 .expect("Invalid template format");
147
148 let real: Vec<DataWrapper> = (1..1000)
83c7162d
XL
149 .map(|i| DataWrapper {
150 v: format!("n={}", i),
151 })
ea8adc8c
XL
152 .collect();
153 let dummy: Vec<DataWrapper> = (1..1000)
83c7162d
XL
154 .map(|i| DataWrapper {
155 v: format!("n={}", i),
156 })
ea8adc8c
XL
157 .collect();
158 let rows = RowWrapper { real, dummy };
f9f354fc 159
3dfed10e 160 let ctx = Context::wraps(&rows).unwrap();
f9f354fc 161 c.bench_function("large_loop_helper", move |b| {
3dfed10e
XL
162 b.iter(|| handlebars.render_with_context("test", &ctx).ok().unwrap())
163 });
164}
165
166fn large_loop_helper_with_context_creation(c: &mut Criterion) {
167 let mut handlebars = Handlebars::new();
168 handlebars
169 .register_template_string("test", "BEFORE\n{{#each real}}{{this.v}}{{/each}}AFTER")
170 .ok()
171 .expect("Invalid template format");
172
173 let real: Vec<DataWrapper> = (1..1000)
174 .map(|i| DataWrapper {
175 v: format!("n={}", i),
176 })
177 .collect();
178 let dummy: Vec<DataWrapper> = (1..1000)
179 .map(|i| DataWrapper {
180 v: format!("n={}", i),
181 })
182 .collect();
183 let rows = RowWrapper { real, dummy };
184
185 c.bench_function("large_loop_helper_with_context_creation", move |b| {
f9f354fc
XL
186 b.iter(|| handlebars.render("test", &rows).ok().unwrap())
187 });
ea8adc8c 188}
f9f354fc
XL
189
190fn large_nested_loop(c: &mut Criterion) {
191 let mut handlebars = Handlebars::new();
192 handlebars
193 .register_template_string(
194 "test",
195 "BEFORE\n{{#each parent as |child|}}{{#each child}}{{this.v}}{{/each}}{{/each}}AFTER",
196 )
197 .ok()
198 .expect("Invalid template format");
199
200 let parent: Vec<Vec<DataWrapper>> = (1..100)
201 .map(|_| {
202 (1..10)
203 .map(|v| DataWrapper {
204 v: format!("v={}", v),
205 })
206 .collect()
207 })
208 .collect();
209
210 let rows = NestedRowWrapper { parent };
211
3dfed10e 212 let ctx = Context::wraps(&rows).unwrap();
f9f354fc 213 c.bench_function("large_nested_loop", move |b| {
3dfed10e 214 b.iter(|| handlebars.render_with_context("test", &ctx).ok().unwrap())
f9f354fc
XL
215 });
216}
217
94222f64 218#[cfg(unix)]
f9f354fc
XL
219criterion_group!(
220 name = benches;
221 config = profiled();
3dfed10e 222 targets = parse_template, render_template, large_loop_helper, large_loop_helper_with_context_creation,
94222f64 223 large_nested_loop
f9f354fc 224);
94222f64
XL
225
226#[cfg(not(unix))]
227criterion_group!(
228 benches,
229 parse_template,
230 render_template,
231 large_loop_helper,
232 large_loop_helper_with_context_creation,
233 large_nested_loop
234);
235
f9f354fc 236criterion_main!(benches);