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 | ||||
| - Collections are smart pointers for many objects at a time, and reallocate | ||||
|   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) | ||||
|  | ||||
| # 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), | ||||
| 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 | ||||
|  | ||||
| @ -178,8 +186,8 @@ to know that alternatives exist if you need them. | ||||
| When it comes to some of the standard library smart pointers | ||||
| ([`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 | ||||
| are provided in crates like [spin](https://crates.io/crates/spin) and | ||||
| [parking_lot](https://crates.io/crates/parking_lot). You can check out | ||||
| are provided in crates like [parking_lot](https://crates.io/crates/parking_lot) and | ||||
| [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::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) | ||||
|  | ||||
| @ -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. | ||||
| - [`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. | ||||
| - [`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 | ||||
|  | ||||
| @ -451,12 +455,12 @@ used for objects that aren't heap allocated, but it technically can be done. | ||||
|  | ||||
| # 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) | ||||
| 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). | ||||
| 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),  | ||||
| *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 | ||||
| [`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