Still need to address lazy_static, thread_local, and iterators

This commit is contained in:
Bradlee Speice 2019-02-06 23:48:43 -05:00
parent f32b107d73
commit 05e0f68c23
No known key found for this signature in database
GPG Key ID: 48BEA6257238E620
2 changed files with 35 additions and 8 deletions

View File

@ -72,7 +72,7 @@ we'll follow this guide:
- Smart pointers hold their contents in the heap - Smart pointers hold their contents in the heap
- Collections are smart pointers for many objects at a time, and reallocate - Collections are smart pointers for many objects at a time, and reallocate
when they need to grow when they need to grow
- `lazy_static!` and `thread_local!` force heap allocation - `lazy_static!` and `thread_local!` force heap allocation for everything.
- Stack-based alternatives to standard library types should be preferred (spin, parking_lot) - Stack-based alternatives to standard library types should be preferred (spin, parking_lot)
# Smart pointers # Smart pointers
@ -166,7 +166,15 @@ will ever be dispatched. A couple of places to look at for confirming this behav
[`HashMap::new()`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.new), [`HashMap::new()`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.new),
and [`String::new()`](https://doc.rust-lang.org/std/string/struct.String.html#method.new). and [`String::new()`](https://doc.rust-lang.org/std/string/struct.String.html#method.new).
# **thread_local!** and **lazy_static!** # **lazy_static!** and **thread_local!**
There are two macros worth addressing in a conversation about heap memory. The first isn't part
of the standard library, but it's the [5th most downloaded crate](https://crates.io/crates/lazy_static)
in Rust. The second
TODO: Not so sure about lazy_static anymore. Is thread_local possibly heap-allocated too?
- Think it may actually be that lazy_static has a no_std mode that uses `spin`, std-mode uses std::Once.
- Reasonably confident thread_local always allocates
# Heap Alternatives # Heap Alternatives
@ -178,8 +186,8 @@ to know that alternatives exist if you need them.
When it comes to some of the standard library smart pointers When it comes to some of the standard library smart pointers
([`RwLock`](https://doc.rust-lang.org/std/sync/struct.RwLock.html) and ([`RwLock`](https://doc.rust-lang.org/std/sync/struct.RwLock.html) and
[`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html)), stack-based alternatives [`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html)), stack-based alternatives
are provided in crates like [spin](https://crates.io/crates/spin) and are provided in crates like [parking_lot](https://crates.io/crates/parking_lot) and
[parking_lot](https://crates.io/crates/parking_lot). You can check out [spin](https://crates.io/crates/spin). You can check out
[`lock_api::RwLock`](https://docs.rs/lock_api/0.1.5/lock_api/struct.RwLock.html), [`lock_api::RwLock`](https://docs.rs/lock_api/0.1.5/lock_api/struct.RwLock.html),
[`lock_api::Mutex`](https://docs.rs/lock_api/0.1.5/lock_api/struct.Mutex.html), and [`lock_api::Mutex`](https://docs.rs/lock_api/0.1.5/lock_api/struct.Mutex.html), and
[`spin::Once`](https://mvdnes.github.io/rust-docs/spin-rs/spin/struct.Once.html) [`spin::Once`](https://mvdnes.github.io/rust-docs/spin-rs/spin/struct.Once.html)

View File

@ -100,6 +100,10 @@ With all that in mind, let's talk about situations in which we're guaranteed to
- Generics will use stack allocation, even with dynamic dispatch. - Generics will use stack allocation, even with dynamic dispatch.
- [`Copy`](https://doc.rust-lang.org/std/marker/trait.Copy.html) types are guaranteed to be - [`Copy`](https://doc.rust-lang.org/std/marker/trait.Copy.html) types are guaranteed to be
stack-allocated, and copying them will be done in stack memory. stack-allocated, and copying them will be done in stack memory.
- [`Iterator`s](https://doc.rust-lang.org/std/iter/trait.Iterator.html) in the standard library
are stack-allocated. No worrying about some
["managed languages"](https://www.youtube.com/watch?v=bSkpMdDe4g4&feature=youtu.be&t=357)
creating garbage.
# Structs # Structs
@ -451,12 +455,12 @@ used for objects that aren't heap allocated, but it technically can be done.
# Copy types # Copy types
Understanding move semantics and copy semantics in Rust is hard. The Rust docs Understanding move semantics and copy semantics in Rust is weird at first. The Rust docs
[go into detail](https://doc.rust-lang.org/stable/core/marker/trait.Copy.html) [go into detail](https://doc.rust-lang.org/stable/core/marker/trait.Copy.html)
far better than can be addressed here, so I'll leave them to do the job. far better than can be addressed here, so I'll leave them to do the job.
Their guideline is reasonable though: Even from a memory perspective though, their guideline is reasonable:
[if your type can implemement `Copy`, it should](https://doc.rust-lang.org/stable/core/marker/trait.Copy.html#when-should-my-type-be-copy). [if your type can implemement `Copy`, it should](https://doc.rust-lang.org/stable/core/marker/trait.Copy.html#when-should-my-type-be-copy).
While there are potential speed tradeoffs to benchmark when discussing `Copy` While there are potential speed tradeoffs to *benchmark* when discussing `Copy`
(move semantics for stack objects vs. copying stack pointers vs. copying stack `struct`s), (move semantics for stack objects vs. copying stack pointers vs. copying stack `struct`s),
*it's impossible for `Copy` to introduce a heap allocation*. *it's impossible for `Copy` to introduce a heap allocation*.
@ -471,4 +475,19 @@ Thus, assignments involving heap types are always move semantics, and new heap
allocations won't occur without explicit calls to allocations won't occur without explicit calls to
[`clone()`](https://doc.rust-lang.org/std/clone/trait.Clone.html#tymethod.clone). [`clone()`](https://doc.rust-lang.org/std/clone/trait.Clone.html#tymethod.clone).
TODO: Some examples. Maybe just need to show compiler errors? ```rust
#[derive(Clone)]
struct Cloneable {
x: Box<u64>
}
// error[E0204]: the trait `Copy` may not be implemented for this type
#[derive(Copy, Clone)]
struct NotCopyable {
x: Box<u64>
}
```
-- [Compiler Explorer](https://godbolt.org/z/VToRuK)
# Iterators