mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-02 07:20:55 +00:00
book: add page about FastWritable
This commit is contained in:
parent
7881bc131b
commit
94fddd4df5
@ -24,6 +24,27 @@ monomorphised code. On average, expect `.to_string()` to be 100% to 200% slower
|
|||||||
[`.to_string()`]: <https://doc.rust-lang.org/stable/std/string/trait.ToString.html#tymethod.to_string>
|
[`.to_string()`]: <https://doc.rust-lang.org/stable/std/string/trait.ToString.html#tymethod.to_string>
|
||||||
[`format!()`]: <https://doc.rust-lang.org/stable/std/fmt/fn.format.html>
|
[`format!()`]: <https://doc.rust-lang.org/stable/std/fmt/fn.format.html>
|
||||||
|
|
||||||
|
## Faster Rendering of Custom Types
|
||||||
|
|
||||||
|
Every type that implements [`fmt::Display`] can be used in askama expressions: `{{ value }}`.
|
||||||
|
Rendering with `fmt::Display` can be slow, though, because it uses [dynamic methods calls] in its
|
||||||
|
[`fmt::Formatter`] argument. To speed up rendering (by a lot, actually),
|
||||||
|
askama adds the trait [`FastWritable`]. For any custom type you want to render,
|
||||||
|
it has to implement `fmt::Display`, but if it also implements `FastWritable`,
|
||||||
|
then – using [autoref-based specialization] – the latter implementation is automatically preferred.
|
||||||
|
|
||||||
|
To reduce the amount of code duplication, you can let your `fmt::Display` implementation call
|
||||||
|
your `FastWritable` implementation:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
{{#include ../../testing/tests/book_example_performance_fmt_call_fast_writable.rs}}
|
||||||
|
```
|
||||||
|
|
||||||
|
[`fmt::Display`]: <https://doc.rust-lang.org/stable/std/fmt/trait.Display.html>
|
||||||
|
[`fmt::Formatter`]: <https://doc.rust-lang.org/stable/std/fmt/struct.Formatter.html>
|
||||||
|
[`FastWritable`]: <./doc/askama/filters/trait.FastWritable.html>
|
||||||
|
[autoref-based specialization]: <https://lukaskalbertodt.github.io/2019/12/05/generalized-autoref-based-specialization.html>
|
||||||
|
|
||||||
## Slow Debug Recompilations
|
## Slow Debug Recompilations
|
||||||
|
|
||||||
If you experience slow compile times when iterating with lots of templates,
|
If you experience slow compile times when iterating with lots of templates,
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
|
use askama::NO_VALUES;
|
||||||
|
use askama::filters::FastWritable;
|
||||||
|
|
||||||
|
// In a real application, please have a look at
|
||||||
|
// https://github.com/kdeldycke/awesome-falsehood/blob/690a070/readme.md#human-identity
|
||||||
|
struct Name<'a> {
|
||||||
|
forename: &'a str,
|
||||||
|
surname: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Name<'_> {
|
||||||
|
// Because the method simply forwards the call, it should be `inline`.
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
// `fmt::Write` has no access to runtime values,
|
||||||
|
// so simply pass `NO_VALUES`.
|
||||||
|
self.write_into(f, NO_VALUES)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FastWritable for Name<'_> {
|
||||||
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
_values: &dyn askama::Values,
|
||||||
|
) -> askama::Result<()> {
|
||||||
|
dest.write_str(self.surname)?;
|
||||||
|
dest.write_str(", ")?;
|
||||||
|
dest.write_str(self.forename)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn both_implementations_should_render_the_same_text() {
|
||||||
|
let person = Name {
|
||||||
|
forename: "Max",
|
||||||
|
surname: "Mustermann",
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buf_fmt = String::new();
|
||||||
|
write!(buf_fmt, "{person}").unwrap();
|
||||||
|
|
||||||
|
let mut buf_fast = String::new();
|
||||||
|
person.write_into(&mut buf_fast, NO_VALUES).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(buf_fmt, buf_fast);
|
||||||
|
assert_eq!(buf_fmt, "Mustermann, Max");
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user