about summary refs log tree commit diff
path: root/docs/dev
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2020-08-24 12:49:36 +0200
committerAleksey Kladov <aleksey.kladov@gmail.com>2020-08-24 12:49:36 +0200
commitfc3e591bdb28745ef29e90de2c1625e6d4e4a229 (patch)
treebf0d57ad3c6ba18bff21cfdc3a2eb97784a764d7 /docs/dev
parente65d48d1fb3d4d91d9dc1148a7a836ff5c9a3c87 (diff)
downloadrust-fc3e591bdb28745ef29e90de2c1625e6d4e4a229.tar.gz
rust-fc3e591bdb28745ef29e90de2c1625e6d4e4a229.zip
Avoid monomorphization
Diffstat (limited to 'docs/dev')
-rw-r--r--docs/dev/style.md35
1 files changed, 35 insertions, 0 deletions
diff --git a/docs/dev/style.md b/docs/dev/style.md
index 44f0956c247..ae69cf1a743 100644
--- a/docs/dev/style.md
+++ b/docs/dev/style.md
@@ -231,6 +231,41 @@ if words.len() != 2 {
 }
 ```
 
+# Avoid Monomorphization
+
+Rust uses monomorphization to compile generic code, meaning that for each instantiation of a generic functions with concrete types, the function is compiled afresh, *per crate*.
+This allows for exceptionally good performance, but leads to increased compile times.
+Runtime performance obeys 80%/20% rule -- only a small fraction of code is hot.
+Compile time **does not** obey this rule -- all code has to be compiled.
+For this reason, avoid making a lot of code type parametric, *especially* on the boundaries between crates.
+
+```rust
+// Good
+fn frbonicate(f: impl FnMut()) {
+    frobnicate_impl(&mut f)
+}
+fn frobnicate_impl(f: &mut dyn FnMut()) {
+    // lots of code
+}
+
+// Not as good
+fn frbonicate(f: impl FnMut()) {
+    // lots of code
+}
+```
+
+Avoid `AsRef` polymorphism, it pays back only for widely used libraries:
+
+```rust
+// Good
+fn frbonicate(f: &Path) {
+}
+
+// Not as good
+fn frbonicate(f: impl AsRef<Path>) {
+}
+```
+
 # Documentation
 
 For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines.