mirror of
				https://github.com/bspeice/speice.io
				synced 2025-10-31 09:30:32 -04:00 
			
		
		
		
	Still need to address lazy_static, thread_local, and iterators
This commit is contained in:
		| @ -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 | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user