iai_callgrind/
lib_bench.rs

1use std::ffi::OsString;
2
3use derive_more::AsRef;
4use iai_callgrind_macros::IntoInner;
5
6use crate::{internal, EntryPoint};
7
8/// The main configuration of a library benchmark.
9///
10/// See [`LibraryBenchmarkConfig::callgrind_args`] for more details.
11///
12/// # Examples
13///
14/// ```rust
15/// # use iai_callgrind::{library_benchmark, library_benchmark_group};
16/// use iai_callgrind::{LibraryBenchmarkConfig, main};
17/// # #[library_benchmark]
18/// # fn some_func() {}
19/// # library_benchmark_group!(name = some_group; benchmarks = some_func);
20/// # fn main() {
21/// main!(
22///     config = LibraryBenchmarkConfig::default()
23///                 .callgrind_args(["toggle-collect=something"]);
24///     library_benchmark_groups = some_group
25/// );
26/// # }
27/// ```
28#[derive(Debug, Default, IntoInner, AsRef, Clone)]
29pub struct LibraryBenchmarkConfig(internal::InternalLibraryBenchmarkConfig);
30
31impl LibraryBenchmarkConfig {
32    /// Create a new `LibraryBenchmarkConfig` with initial callgrind arguments
33    ///
34    /// See also [`LibraryBenchmarkConfig::callgrind_args`].
35    ///
36    /// # Examples
37    ///
38    /// ```rust
39    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
40    /// # #[library_benchmark]
41    /// # fn some_func() {}
42    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
43    /// # fn main() {
44    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
45    ///
46    /// main!(
47    ///     config =
48    ///         LibraryBenchmarkConfig::with_callgrind_args(["toggle-collect=something"]);
49    ///     library_benchmark_groups = some_group
50    /// );
51    /// # }
52    /// ```
53    #[deprecated = "Please use with_callgrind_args"]
54    pub fn with_raw_callgrind_args<I, T>(args: T) -> Self
55    where
56        I: AsRef<str>,
57        T: IntoIterator<Item = I>,
58    {
59        Self(internal::InternalLibraryBenchmarkConfig {
60            env_clear: Option::default(),
61            callgrind_args: internal::InternalRawArgs::from_iter(args),
62            valgrind_args: internal::InternalRawArgs::default(),
63            envs: Vec::default(),
64            flamegraph_config: Option::default(),
65            regression_config: Option::default(),
66            tools: internal::InternalTools::default(),
67            tools_override: Option::default(),
68            output_format: Option::default(),
69            entry_point: Option::default(),
70        })
71    }
72
73    /// Add callgrind arguments to this `LibraryBenchmarkConfig`
74    ///
75    /// The arguments don't need to start with a flag: `--toggle-collect=some` or
76    /// `toggle-collect=some` are both understood.
77    ///
78    /// Not all callgrind arguments are understood by `iai-callgrind` or cause problems in
79    /// `iai-callgrind` if they would be applied. `iai-callgrind` will issue a warning in such
80    /// cases. Most of the defaults can be overwritten. The default settings are:
81    ///
82    /// * `--I1=32768,8,64`
83    /// * `--D1=32768,8,64`
84    /// * `--LL=8388608,16,64`
85    /// * `--cache-sim=yes`
86    /// * `--toggle-collect=...` (see also [`LibraryBenchmarkConfig::entry_point`])
87    /// * `--collect-atstart=no`
88    /// * `--compress-pos=no`
89    /// * `--compress-strings=no`
90    ///
91    /// Note that `toggle-collect` is an array and the default [`EntryPoint`] for library benchmarks
92    /// is the benchmark function.
93    ///
94    /// See also [Callgrind Command-line
95    /// Options](https://valgrind.org/docs/manual/cl-manual.html#cl-manual.options)
96    ///
97    /// # Examples
98    ///
99    /// ```rust
100    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
101    /// # #[library_benchmark]
102    /// # fn some_func() {}
103    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
104    /// # fn main() {
105    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
106    ///
107    /// main!(
108    ///     config = LibraryBenchmarkConfig::default()
109    ///                 .callgrind_args(["toggle-collect=something"]);
110    ///     library_benchmark_groups = some_group
111    /// );
112    /// # }
113    /// ```
114    #[deprecated = "Please use callgrind_args"]
115    pub fn raw_callgrind_args<I, T>(&mut self, args: T) -> &mut Self
116    where
117        I: AsRef<str>,
118        T: IntoIterator<Item = I>,
119    {
120        #[allow(deprecated)]
121        self.raw_callgrind_args_iter(args);
122        self
123    }
124
125    /// Add elements of an iterator over callgrind arguments to this `LibraryBenchmarkConfig`
126    ///
127    /// See also [`LibraryBenchmarkConfig::callgrind_args`]
128    ///
129    /// # Examples
130    ///
131    /// ```rust
132    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
133    /// # #[library_benchmark]
134    /// # fn some_func() {}
135    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
136    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
137    ///
138    /// # fn main() {
139    /// main!(
140    ///     config = LibraryBenchmarkConfig::default()
141    ///                 .raw_callgrind_args_iter(["toggle-collect=something"].iter());
142    ///     library_benchmark_groups = some_group
143    /// );
144    /// # }
145    /// ```
146    #[deprecated = "Please use callgrind_args"]
147    pub fn raw_callgrind_args_iter<I, T>(&mut self, args: T) -> &mut Self
148    where
149        I: AsRef<str>,
150        T: IntoIterator<Item = I>,
151    {
152        self.0.callgrind_args.extend_ignore_flag(args);
153        self
154    }
155
156    /// Create a new `LibraryBenchmarkConfig` with callgrind arguments
157    ///
158    /// See also [`LibraryBenchmarkConfig::callgrind_args`].
159    ///
160    /// # Examples
161    ///
162    /// ```rust
163    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
164    /// # #[library_benchmark]
165    /// # fn some_func() {}
166    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
167    /// # fn main() {
168    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
169    ///
170    /// main!(
171    ///     config =
172    ///         LibraryBenchmarkConfig::with_callgrind_args(["toggle-collect=something"]);
173    ///     library_benchmark_groups = some_group
174    /// );
175    /// # }
176    /// ```
177    pub fn with_callgrind_args<I, T>(args: T) -> Self
178    where
179        I: AsRef<str>,
180        T: IntoIterator<Item = I>,
181    {
182        Self(internal::InternalLibraryBenchmarkConfig {
183            callgrind_args: internal::InternalRawArgs::from_iter(args),
184            ..Default::default()
185        })
186    }
187
188    /// Add callgrind arguments to this `LibraryBenchmarkConfig`
189    ///
190    /// The arguments don't need to start with a flag: `--toggle-collect=some` or
191    /// `toggle-collect=some` are both understood.
192    ///
193    /// Not all callgrind arguments are understood by `iai-callgrind` or cause problems in
194    /// `iai-callgrind` if they would be applied. `iai-callgrind` will issue a warning in such
195    /// cases. Most of the defaults can be overwritten. The default settings are:
196    ///
197    /// * `--I1=32768,8,64`
198    /// * `--D1=32768,8,64`
199    /// * `--LL=8388608,16,64`
200    /// * `--cache-sim=yes`
201    /// * `--toggle-collect=...` (see also [`LibraryBenchmarkConfig::entry_point`])
202    /// * `--collect-atstart=no`
203    /// * `--compress-pos=no`
204    /// * `--compress-strings=no`
205    ///
206    /// Note that `toggle-collect` is an array and the default [`EntryPoint`] for library benchmarks
207    /// is the benchmark function.
208    ///
209    /// See also [Callgrind Command-line
210    /// Options](https://valgrind.org/docs/manual/cl-manual.html#cl-manual.options)
211    ///
212    /// # Examples
213    ///
214    /// ```rust
215    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
216    /// # #[library_benchmark]
217    /// # fn some_func() {}
218    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
219    /// # fn main() {
220    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
221    ///
222    /// main!(
223    ///     config = LibraryBenchmarkConfig::default()
224    ///                 .callgrind_args(["toggle-collect=something"]);
225    ///     library_benchmark_groups = some_group
226    /// );
227    /// # }
228    /// ```
229    pub fn callgrind_args<I, T>(&mut self, args: T) -> &mut Self
230    where
231        I: AsRef<str>,
232        T: IntoIterator<Item = I>,
233    {
234        self.0.callgrind_args.extend_ignore_flag(args);
235        self
236    }
237
238    /// Pass valgrind arguments to all tools
239    ///
240    /// Only core [valgrind
241    /// arguments](https://valgrind.org/docs/manual/manual-core.html#manual-core.options) are
242    /// allowed.
243    ///
244    /// These arguments can be overwritten by tool specific arguments for example with
245    /// [`LibraryBenchmarkConfig::callgrind_args`] or [`crate::Tool::args`].
246    ///
247    /// # Examples
248    ///
249    /// Specify `--trace-children=no` for all configured tools (including callgrind):
250    ///
251    /// ```rust
252    /// # use iai_callgrind::{library_benchmark_group, library_benchmark};
253    /// # #[library_benchmark] fn bench_me() {}
254    /// # library_benchmark_group!(
255    /// #    name = my_group;
256    /// #    benchmarks = bench_me
257    /// # );
258    /// use iai_callgrind::{main, LibraryBenchmarkConfig, Tool, ValgrindTool};
259    ///
260    /// # fn main() {
261    /// main!(
262    ///     config = LibraryBenchmarkConfig::default()
263    ///         .valgrind_args(["--trace-children=no"])
264    ///         .tool(Tool::new(ValgrindTool::DHAT));
265    ///     library_benchmark_groups = my_group
266    /// );
267    /// # }
268    /// ```
269    ///
270    /// Overwrite the valgrind argument `--num-callers=25` for `DHAT` with `--num-callers=30`:
271    ///
272    /// ```rust
273    /// # use iai_callgrind::{library_benchmark_group, library_benchmark};
274    /// # #[library_benchmark] fn bench_me() {}
275    /// # library_benchmark_group!(
276    /// #    name = my_group;
277    /// #    benchmarks = bench_me
278    /// # );
279    /// use iai_callgrind::{main, LibraryBenchmarkConfig, Tool, ValgrindTool};
280    ///
281    /// # fn main() {
282    /// main!(
283    ///     config = LibraryBenchmarkConfig::default()
284    ///         .valgrind_args(["--num-callers=25"])
285    ///         .tool(Tool::new(ValgrindTool::DHAT)
286    ///             .args(["--num-callers=30"])
287    ///         );
288    ///     library_benchmark_groups = my_group
289    /// );
290    /// # }
291    /// ```
292    pub fn valgrind_args<I, T>(&mut self, args: T) -> &mut Self
293    where
294        I: AsRef<str>,
295        T: IntoIterator<Item = I>,
296    {
297        self.0.valgrind_args.extend_ignore_flag(args);
298        self
299    }
300
301    /// Clear the environment variables before running a benchmark (Default: true)
302    ///
303    /// # Examples
304    ///
305    /// ```rust
306    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
307    /// # #[library_benchmark]
308    /// # fn some_func() {}
309    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
310    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
311    ///
312    /// # fn main() {
313    /// main!(
314    ///     config = LibraryBenchmarkConfig::default().env_clear(false);
315    ///     library_benchmark_groups = some_group
316    /// );
317    /// # }
318    /// ```
319    pub fn env_clear(&mut self, value: bool) -> &mut Self {
320        self.0.env_clear = Some(value);
321        self
322    }
323
324    /// Add an environment variables which will be available in library benchmarks
325    ///
326    /// These environment variables are available independently of the setting of
327    /// [`LibraryBenchmarkConfig::env_clear`].
328    ///
329    /// # Examples
330    ///
331    /// An example for a custom environment variable, available in all benchmarks:
332    ///
333    /// ```rust
334    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
335    /// # #[library_benchmark]
336    /// # fn some_func() {}
337    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
338    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
339    ///
340    /// # fn main() {
341    /// main!(
342    ///     config = LibraryBenchmarkConfig::default().env("FOO", "BAR");
343    ///     library_benchmark_groups = some_group
344    /// );
345    /// # }
346    /// ```
347    pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
348    where
349        K: Into<OsString>,
350        V: Into<OsString>,
351    {
352        self.0.envs.push((key.into(), Some(value.into())));
353        self
354    }
355
356    /// Add multiple environment variables which will be available in library benchmarks
357    ///
358    /// See also [`LibraryBenchmarkConfig::env`] for more details.
359    ///
360    /// # Examples
361    ///
362    /// ```rust
363    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
364    /// # #[library_benchmark]
365    /// # fn some_func() {}
366    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
367    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
368    ///
369    /// # fn main() {
370    /// main!(
371    ///     config =
372    ///         LibraryBenchmarkConfig::default().envs([("MY_CUSTOM_VAR", "SOME_VALUE"), ("FOO", "BAR")]);
373    ///     library_benchmark_groups = some_group
374    /// );
375    /// # }
376    /// ```
377    pub fn envs<K, V, T>(&mut self, envs: T) -> &mut Self
378    where
379        K: Into<OsString>,
380        V: Into<OsString>,
381        T: IntoIterator<Item = (K, V)>,
382    {
383        self.0
384            .envs
385            .extend(envs.into_iter().map(|(k, v)| (k.into(), Some(v.into()))));
386        self
387    }
388
389    /// Specify a pass-through environment variable
390    ///
391    /// Usually, the environment variables before running a library benchmark are cleared
392    /// but specifying pass-through variables makes this environment variable available to
393    /// the benchmark as it actually appeared in the root environment.
394    ///
395    /// Pass-through environment variables are ignored if they don't exist in the root
396    /// environment.
397    ///
398    /// # Examples
399    ///
400    /// Here, we chose to pass through the original value of the `HOME` variable:
401    ///
402    /// ```rust
403    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
404    /// # #[library_benchmark]
405    /// # fn some_func() {}
406    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
407    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
408    ///
409    /// # fn main() {
410    /// main!(
411    ///     config = LibraryBenchmarkConfig::default().pass_through_env("HOME");
412    ///     library_benchmark_groups = some_group
413    /// );
414    /// # }
415    /// ```
416    pub fn pass_through_env<K>(&mut self, key: K) -> &mut Self
417    where
418        K: Into<OsString>,
419    {
420        self.0.envs.push((key.into(), None));
421        self
422    }
423
424    /// Specify multiple pass-through environment variables
425    ///
426    /// See also [`LibraryBenchmarkConfig::pass_through_env`].
427    ///
428    /// # Examples
429    ///
430    /// ```rust
431    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
432    /// # #[library_benchmark]
433    /// # fn some_func() {}
434    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
435    /// use iai_callgrind::{LibraryBenchmarkConfig, main};
436    ///
437    /// # fn main() {
438    /// main!(
439    ///     config = LibraryBenchmarkConfig::default().pass_through_envs(["HOME", "USER"]);
440    ///     library_benchmark_groups = some_group
441    /// );
442    /// # }
443    /// ```
444    pub fn pass_through_envs<K, T>(&mut self, envs: T) -> &mut Self
445    where
446        K: Into<OsString>,
447        T: IntoIterator<Item = K>,
448    {
449        self.0
450            .envs
451            .extend(envs.into_iter().map(|k| (k.into(), None)));
452        self
453    }
454
455    /// Option to produce flamegraphs from callgrind output using the [`crate::FlamegraphConfig`]
456    ///
457    /// # Examples
458    ///
459    /// ```rust
460    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
461    /// # #[library_benchmark]
462    /// # fn some_func() {}
463    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
464    /// use iai_callgrind::{LibraryBenchmarkConfig, main, FlamegraphConfig};
465    ///
466    /// # fn main() {
467    /// main!(
468    ///     config = LibraryBenchmarkConfig::default().flamegraph(FlamegraphConfig::default());
469    ///     library_benchmark_groups = some_group
470    /// );
471    /// # }
472    /// ```
473    pub fn flamegraph<T>(&mut self, config: T) -> &mut Self
474    where
475        T: Into<internal::InternalFlamegraphConfig>,
476    {
477        self.0.flamegraph_config = Some(config.into());
478        self
479    }
480
481    /// Enable performance regression checks with a [`crate::RegressionConfig`]
482    ///
483    /// # Examples
484    ///
485    /// ```rust
486    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
487    /// # #[library_benchmark]
488    /// # fn some_func() {}
489    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
490    /// use iai_callgrind::{LibraryBenchmarkConfig, main, RegressionConfig};
491    ///
492    /// # fn main() {
493    /// main!(
494    ///     config = LibraryBenchmarkConfig::default().regression(RegressionConfig::default());
495    ///     library_benchmark_groups = some_group
496    /// );
497    /// # }
498    /// ```
499    pub fn regression<T>(&mut self, config: T) -> &mut Self
500    where
501        T: Into<internal::InternalRegressionConfig>,
502    {
503        self.0.regression_config = Some(config.into());
504        self
505    }
506
507    /// Add a configuration to run a valgrind [`crate::Tool`] in addition to callgrind
508    ///
509    /// # Examples
510    ///
511    /// ```rust
512    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
513    /// # #[library_benchmark]
514    /// # fn some_func() {}
515    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
516    /// use iai_callgrind::{LibraryBenchmarkConfig, main, Tool, ValgrindTool};
517    ///
518    /// # fn main() {
519    /// main!(
520    ///     config = LibraryBenchmarkConfig::default()
521    ///         .tool(Tool::new(ValgrindTool::DHAT));
522    ///     library_benchmark_groups = some_group
523    /// );
524    /// # }
525    /// ```
526    pub fn tool<T>(&mut self, tool: T) -> &mut Self
527    where
528        T: Into<internal::InternalTool>,
529    {
530        self.0.tools.update(tool.into());
531        self
532    }
533
534    /// Add multiple configurations to run valgrind [`crate::Tool`]s in addition to callgrind
535    ///
536    /// # Examples
537    ///
538    /// ```rust
539    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
540    /// # #[library_benchmark]
541    /// # fn some_func() {}
542    /// # library_benchmark_group!(name = some_group; benchmarks = some_func);
543    /// use iai_callgrind::{LibraryBenchmarkConfig, main, Tool, ValgrindTool};
544    ///
545    /// # fn main() {
546    /// main!(
547    ///     config = LibraryBenchmarkConfig::default()
548    ///         .tools(
549    ///             [
550    ///                 Tool::new(ValgrindTool::DHAT),
551    ///                 Tool::new(ValgrindTool::Massif)
552    ///             ]
553    ///         );
554    ///     library_benchmark_groups = some_group
555    /// );
556    /// # }
557    /// ```
558    pub fn tools<I, T>(&mut self, tools: T) -> &mut Self
559    where
560        I: Into<internal::InternalTool>,
561        T: IntoIterator<Item = I>,
562    {
563        self.0.tools.update_all(tools.into_iter().map(Into::into));
564        self
565    }
566
567    /// Override previously defined configurations of valgrind [`crate::Tool`]s
568    ///
569    /// Usually, if specifying [`crate::Tool`] configurations with [`LibraryBenchmarkConfig::tool`]
570    /// these tools are appended to the configuration of a [`LibraryBenchmarkConfig`] of
571    /// higher-levels. Specifying a [`crate::Tool`] with this method overrides previously defined
572    /// configurations.
573    ///
574    /// Note that [`crate::Tool`]s specified with [`LibraryBenchmarkConfig::tool`] will be ignored,
575    /// if in the very same `LibraryBenchmarkConfig`, [`crate::Tool`]s are specified by this method
576    /// (or [`LibraryBenchmarkConfig::tools_override`]).
577    ///
578    /// # Examples
579    ///
580    /// The following will run `DHAT` and `Massif` (and the default callgrind) for all benchmarks in
581    /// `main!` besides for `some_func` which will just run `Memcheck` (and callgrind).
582    ///
583    /// ```rust
584    /// use iai_callgrind::{
585    ///     main, library_benchmark, library_benchmark_group, LibraryBenchmarkConfig, Tool, ValgrindTool
586    /// };
587    ///
588    /// #[library_benchmark(config = LibraryBenchmarkConfig::default()
589    ///     .tool_override(
590    ///         Tool::new(ValgrindTool::Memcheck)
591    ///     )
592    /// )]
593    /// fn some_func() {}
594    ///
595    /// library_benchmark_group!(
596    ///     name = some_group;
597    ///     benchmarks = some_func
598    /// );
599    ///
600    /// # fn main() {
601    /// main!(
602    ///     config = LibraryBenchmarkConfig::default()
603    ///         .tools(
604    ///             [
605    ///                 Tool::new(ValgrindTool::DHAT),
606    ///                 Tool::new(ValgrindTool::Massif)
607    ///             ]
608    ///         );
609    ///     library_benchmark_groups = some_group
610    /// );
611    /// # }
612    /// ```
613    pub fn tool_override<T>(&mut self, tool: T) -> &mut Self
614    where
615        T: Into<internal::InternalTool>,
616    {
617        self.0
618            .tools_override
619            .get_or_insert(internal::InternalTools::default())
620            .update(tool.into());
621        self
622    }
623
624    /// Override previously defined configurations of valgrind [`crate::Tool`]s
625    ///
626    /// See also [`LibraryBenchmarkConfig::tool_override`].
627    ///
628    /// # Examples
629    ///
630    /// The following will run `DHAT` (and the default callgrind) for all benchmarks in
631    /// `main!` besides for `some_func` which will run `Massif` and `Memcheck` (and callgrind).
632    ///
633    /// ```rust
634    /// use iai_callgrind::{
635    ///     main, library_benchmark, library_benchmark_group, LibraryBenchmarkConfig, Tool, ValgrindTool
636    /// };
637    ///
638    /// #[library_benchmark(config = LibraryBenchmarkConfig::default()
639    ///     .tools_override([
640    ///         Tool::new(ValgrindTool::Massif),
641    ///         Tool::new(ValgrindTool::Memcheck)
642    ///     ])
643    /// )]
644    /// fn some_func() {}
645    ///
646    /// library_benchmark_group!(
647    ///     name = some_group;
648    ///     benchmarks = some_func
649    /// );
650    ///
651    /// # fn main() {
652    /// main!(
653    ///     config = LibraryBenchmarkConfig::default()
654    ///         .tool(
655    ///             Tool::new(ValgrindTool::DHAT),
656    ///         );
657    ///     library_benchmark_groups = some_group
658    /// );
659    /// # }
660    /// ```
661    pub fn tools_override<I, T>(&mut self, tools: T) -> &mut Self
662    where
663        I: Into<internal::InternalTool>,
664        T: IntoIterator<Item = I>,
665    {
666        self.0
667            .tools_override
668            .get_or_insert(internal::InternalTools::default())
669            .update_all(tools.into_iter().map(Into::into));
670        self
671    }
672
673    /// Set or unset the entry point for a benchmark
674    ///
675    /// Iai-Callgrind sets the [`--toggle-collect`] argument of callgrind to the benchmark function
676    /// which we call [`EntryPoint::Default`]. Specifying a `--toggle-collect` argument, sets
677    /// automatically `--collect-at-start=no`. This ensures that only the metrics from the benchmark
678    /// itself are collected and not the `setup` or `teardown` or anything before/after the
679    /// benchmark function.
680    ///
681    ///
682    /// However, there are cases when the default toggle is not enough [`EntryPoint::Custom`] or in
683    /// the way [`EntryPoint::None`].
684    ///
685    /// Setting [`EntryPoint::Custom`] is convenience for disabling the entry point with
686    /// [`EntryPoint::None`] and setting `--toggle-collect=CUSTOM_ENTRY_POINT` in
687    /// [`LibraryBenchmarkConfig::callgrind_args`]. [`EntryPoint::Custom`] can be useful if you
688    /// want to benchmark a private function and only need the function in the benchmark function as
689    /// access point. [`EntryPoint::Custom`] accepts glob patterns the same way as
690    /// [`--toggle-collect`] does.
691    ///
692    /// # Examples
693    ///
694    /// If you're using callgrind client requests either in the benchmark function itself or in your
695    /// library, then using [`EntryPoint::None`] is presumably be required. Consider the following
696    /// example (`DEFAULT_ENTRY_POINT` marks the default entry point):
697    #[cfg_attr(not(feature = "client_requests_defs"), doc = "```rust,ignore")]
698    #[cfg_attr(feature = "client_requests_defs", doc = "```rust")]
699    /// use iai_callgrind::{
700    ///     main, LibraryBenchmarkConfig,library_benchmark, library_benchmark_group
701    /// };
702    /// use std::hint::black_box;
703    ///
704    /// fn to_be_benchmarked() -> u64 {
705    ///     println!("Some info output");
706    ///     iai_callgrind::client_requests::callgrind::start_instrumentation();
707    ///     let result = {
708    ///         // some heavy calculations
709    /// #       10
710    ///     };
711    ///     iai_callgrind::client_requests::callgrind::stop_instrumentation();
712    ///
713    ///     result
714    /// }
715    ///
716    /// #[library_benchmark]
717    /// fn some_bench() -> u64 { // <-- DEFAULT ENTRY POINT
718    ///     black_box(to_be_benchmarked())
719    /// }
720    ///
721    /// library_benchmark_group!(name = some_group; benchmarks = some_bench);
722    /// # fn main() {
723    /// main!(library_benchmark_groups = some_group);
724    /// # }
725    /// ```
726    /// In the example above [`EntryPoint::Default`] is active, so the counting of events starts
727    /// when the `some_bench` function is entered. In `to_be_benchmarked`, the client request
728    /// `start_instrumentation` does effectively nothing and `stop_instrumentation` will stop the
729    /// event counting as requested. This is most likely not what you intended. The event counting
730    /// should start with `start_instrumentation`. To achieve this, you can set [`EntryPoint::None`]
731    /// which removes the default toggle, but also `--collect-at-start=no`. So, you need to specify
732    /// `--collect-at-start=no` in [`LibraryBenchmarkConfig::callgrind_args`]. The example would
733    /// then look like this:
734    /// ```rust
735    /// use std::hint::black_box;
736    ///
737    /// use iai_callgrind::{library_benchmark, EntryPoint, LibraryBenchmarkConfig};
738    /// # use iai_callgrind::{library_benchmark_group, main};
739    /// # fn to_be_benchmarked() -> u64 { 10 }
740    ///
741    /// // ...
742    ///
743    /// #[library_benchmark(
744    ///     config = LibraryBenchmarkConfig::default()
745    ///         .callgrind_args(["--collect-at-start=no"])
746    ///         .entry_point(EntryPoint::None)
747    /// )]
748    /// fn some_bench() -> u64 {
749    ///     black_box(to_be_benchmarked())
750    /// }
751    ///
752    /// // ...
753    ///
754    /// # library_benchmark_group!(name = some_group; benchmarks = some_bench);
755    /// # fn main() {
756    /// # main!(library_benchmark_groups = some_group);
757    /// # }
758    /// ```
759    /// [`--toggle-collect`]: https://valgrind.org/docs/manual/cl-manual.html#cl-manual.options
760    pub fn entry_point<T>(&mut self, entry_point: T) -> &mut Self
761    where
762        T: Into<EntryPoint>,
763    {
764        self.0.entry_point = Some(entry_point.into());
765        self
766    }
767
768    /// Configure the [`crate::OutputFormat`] of the terminal output of Iai-Callgrind
769    ///
770    /// # Examples
771    ///
772    /// ```rust
773    /// use iai_callgrind::{main, LibraryBenchmarkConfig, OutputFormat};
774    /// # use iai_callgrind::{library_benchmark, library_benchmark_group};
775    /// # #[library_benchmark]
776    /// # fn some_func() {}
777    /// # library_benchmark_group!(
778    /// #    name = some_group;
779    /// #    benchmarks = some_func
780    /// # );
781    /// # fn main() {
782    /// main!(
783    ///     config = LibraryBenchmarkConfig::default()
784    ///         .output_format(OutputFormat::default()
785    ///             .truncate_description(Some(200))
786    ///         );
787    ///     library_benchmark_groups = some_group
788    /// );
789    /// # }
790    pub fn output_format<T>(&mut self, output_format: T) -> &mut Self
791    where
792        T: Into<internal::InternalOutputFormat>,
793    {
794        self.0.output_format = Some(output_format.into());
795        self
796    }
797}