mirror of
https://github.com/bspeice/speice.io
synced 2024-12-22 16:48:10 -05:00
Still need to address lazy_static, thread_local, and iterators
This commit is contained in:
parent
f32b107d73
commit
05e0f68c23
@ -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)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user