Highlighting and parsing procedures — seqalign_pathing: Dynamic programming with A* pathfinding — Rate With Science: Wikipedia link graph search — Dayder: Fast correlation calculations on lots of data
languages — Just not all in the same language, except Rust — http://thume.ca/talks has a link to the slides — Code examples are real code from projects I've worked on — Only adulterated by deleting unimportant lines — Except crate examples, which are from crate docs
I won't break everything — Great compiler errors: I know what I need to change — Great index of these: https://doc.rust-lang.org/error-index.html — Easy testing: Easy to write tests before you refactor
this when learning Xi's codebase, it helped a lot — Confusing naming? Rename it! — Confusing code turns out to be wrong or suboptimal? Fix it! — Spend lots of time understanding something? Add a comment! — Ideally get code review from the original author — You help yourself and everyone who comes after you!
{ let mut sb = SubsetBuilder::new(); let mut i = 0; let mut j = 0; loop { let (next_beg, mut next_end) = if i == self.0.len() { if j == other.0.len() { break; } else { let del = other.0[j]; j += 1; del } } else if j == other.0.len() || self.0[i].0 < other.0[j].0 { let del = self.0[i]; i += 1; del } else { let del = other.0[j]; j += 1; del }; loop { if i < self.0.len() && self.0[i].0 <= next_end { next_end = max(next_end, self.0[i].1); i += 1; continue; } else if j < other.0.len() && other.0[j].0 <= next_end { next_end = max(next_end, other.0[j].1); j += 1; continue; } else { break; } } sb.add_range(next_beg, next_end); } sb.build() } pub fn transform_shrink(&self, other: &Subset) -> Subset { let mut sb = SubsetBuilder::new(); let mut last = 0; let mut i = 0; let mut y = 0; for &(b, e) in &self.0 { if i < other.0.len() && other.0[i].0 < last && other.0[i].1 < b { sb.add_range(y, other.0[i].1 + y - last); i += 1; } while i < other.0.len() && other.0[i].1 < b { sb.add_range(other.0[i].0 + y - last, other.0[i].1 + y - last); i += 1; } if i < other.0.len() && other.0[i].0 < b { sb.add_range(max(last, other.0[i].0) + y - last, b + y - last); } while i < other.0.len() && other.0[i].1 < e { i += 1; } y += b - last; last = e; } if i < other.0.len() && other.0[i].0 < last { sb.add_range(y, other.0[i].1 + y - last); i += 1; } for &(b, e) in &other.0[i..] { sb.add_range(b + y - last, e + y - last); } sb.build() }
your references might form cycles, instead use indices into a Vec that stores all your nodes — Requires passing around a reference to the arena as a parameter ! — Solves mutability, borrow checking and memory management issues — Gives you good node allocation speed and locality as a side effect! "
Using Rc/Weak/RefCell can be a pain to deal with — I used Rc/Weak/RefCell in syntect and regret it — It lead to API gotchas that could cause panics — because of Weaks allowing you to drop necessary state — An arena would have made these mistakes compile errors — It made some things nigh-impossible to parallelize — Made some iterators slow that should have been fast — Accessing things required a bunch of boilerplate
tests — Fastest at byte buffers, but also supports all types quickcheck does — Three crates for different fuzzers: honggfuzz, cargo-fuzz, afl — Doesn't integrate with cargo test like property testing libraries
— crossbeam includes fast lock-free channels, queues, stacks and more — Includes scoped threads that can access stack data — Also includes a library for GC in lock-free data structures
nalgebra: Nice docs, more helpers, more types (e.g Translation) — euclid: Maximum type safety (on the other hand, maximum hassle) use euclid::*; pub struct ScreenSpace; pub type ScreenPoint = TypedPoint2D<f32, ScreenSpace>; pub type ScreenSize = TypedSize2D<f32, ScreenSpace>; pub struct WorldSpace; pub type WorldPoint = TypedPoint3D<f32, WorldSpace>; pub type ProjectionMatrix = TypedTransform3D<f32, WorldSpace, ScreenSpace>;
hashes for are great for many non-crypto purposes — distributed coordination, caches, Merkle trees, etc... use blake2::{Blake2b, Digest}; let mut hasher = Blake2b::new(); hasher.input(b"Hello world!"); hasher.input("String data".as_bytes()); // Note that calling `result()` consumes hasher let hash = hasher.result(); println!("Result: {:x}", hash);
and HashSet — Rust's default hash function is collision attack resistant — fxhash gives that up for speed and can hash 8 bytes at a time — Used in rustc and Servo for a noticeable speedup — indexmap: Hash map with fast iteration, maintains inertion order
— pest: nice parser generator — serde: Automatic serialization/deserialization — Supports many formats and arbitrary data structures — bincode: binary serialization format for serde — good for caches, storing large data structures — itertools: extra iterator functions! — differential-dataflow: some kind of magic incremental parallel distributed dataflow madness, if you can understand it