In November 2021 I wrote a blog post that examined Rust s curious relationship with global variables. It aimed to explain why this ubiquitous language feature required external crates, and ended with personal recommendations on the use of globals in new code. Two years have passed, and Rust has changed enough that it s time to take Continue reading Rust global variables, two years on
False sharing happens when multiple CPU cores modify different but closely located memory, unintentionally sharing a cache line as a result. Atomic operations on memory not shared with other threads are normally uncontended, and therefore almost as fast as non-atomic ones, but false sharing can cause them to execute orders of magnitude more slowly. The Continue reading A close encounter with false…
Some generic functions need to verify properties of the types they accept that are not easy to express using traits, such as that the type s size or layout satisfies a condition. These constraints come from unsafe or FFI code and are generally hard to avoid. Here is a silly function that has two requirements of Continue reading Compile-time checks in generic functions work, and you can use them in…
Decorate-sort-undecorate is a simple sorting pattern known for decades, which was additionally popularized by Randall Schwartz in the context of Perl, earning it the moniker Schwartzian transform. While I ve been aware of the pattern for many years, I only recently realized just how relevant it still is for optimizing everyday sorts. Consider this code that Continue reading Faster sorting with…
Some Rust questions are asked over and over, and are therefore met with short and well-rehearsed answers. Compile in release mode when measuring performance. Don t try to learn Rust with linked lists. Use scoped threads. That requires specialization. But there is one response that is delivered in an almost checkmate-like fashion: You are trying to Continue reading Self-referential types for fun…
You read about faster hash functions and switch to one. Most of your code gets the expected speed boost, but some parts mysteriously get slower much slower, especially when dealing with large hashmaps. If this sounds familiar, you might have encountered the stable HashMap trap. Background Rust s HashMap is an implementation of Google s SwissTable. Continue reading The stable HashMap trap
Let s say you need to match the same regex across a large number of strings perhaps you re applying a grep-like filter to data generated or received by your program. This toy example demonstrates it by matching a regex against half a billion strings: use regex::Regex; lazy_static! { static ref IS_INTEGER: Regex = Regex::new("^[0-9]+$").unwrap(); } Continue reading Contention on multi-threaded…
Rust has a reputation of a language unfriendly to global variables. While this reputation is not entirely undeserved, most of it stems from guarantees afforded by Rust and not by a desire to stifle the programmer s creativity. In this article we ll show how to use global variables, and how to overcome the limitations. Note: this Continue reading Rust global variables demystified
Let s say we re building a simple table indexed by integers starting with 0. Although the keys are contiguous, the table is loaded from key-value pairs that arrive in arbitrary order. The number of elements is not known in advance and can be anywhere from a handful up to a hundred million, but is expected to Continue reading Upgradable parking_lot::RwLock might not be what you expect
In the last several years async-friendly languages and APIs have received a large amount of attention. One contentious point in the language design space are the colored functions , or division of functions to async and non-async ones. The term was introduced by the now-famous 2015 article titled What Color is Your Function?, which uses color Continue reading Rust async is colored, and that s not…