> The default hashing algorithm is not specified, but at the time of writing the default is an algorithm called SipHash 1-3. This algorithm is high quality—it provides high protection against collisions—but is relatively slow, particularly for short keys such as integers.
> An attempt to switch from fxhash back to the default hasher resulted in slowdowns ranging from 4-84%!
I/O
> Rust’s print! and println! macros lock stdout on every call. If you have repeated calls to these macros it may be better to lock stdout manually.
Build times
> If you use dev builds but don’t often use a debugger, consider disabling debuginfo. This can improve dev build times significantly, by as much as 20-40%.
Interesting std library alternatives
> If you have many short vectors, you can use the SmallVec type from the smallvec crate. SmallVec<[T; N]> is a drop-in replacement for Vec that can store N elements within the SmallVec itself, and then switches to a heap allocation if the number of elements exceeds that.
> If you have many short vectors and you precisely know their maximum length, ArrayVec from the arrayvec crate is a better choice than SmallVec. It does not require the fallback to heap allocation, which makes it a little faster.
> The SmallString type from the smallstr crate is similar to the SmallVec type.
I doubt I'll change my use of the standard types often, but this is good information to know for cases where this might be applicable.
Advice on enums
> If an enum has an outsized variant, consider boxing one or more fields.
I'm surprised I didn't see any advice about skipping proc macros or Serde for faster compile times.
the locking of stdout on every call is common amongst a lot of programming languages, a common issue when multi-threading code where every thread is allowed to print to the terminal.
On a 64-bit machine the String type, and likewise a C++ std::string are 24 bytes, 8 bytes for a pointer to the allocated memory on the heap, then twice that for a size and capacity or their pointer equivalents depending on implementation.
The 3rd party library type CompactString can fit up to 24 bytes of UTF-8 text internally, yet it is still the same size as String and just like String, Option<CompactString> is the same size as CompactString. It does add complexity (and of course a library dependency if you care about that) but if you have lots of short strings this may be the best small string type for you.
[The key is UTF-8 encoding can only end with certain bytes, CompactString's documentation explains in more detail]
> > If you use dev builds but don’t often use a debugger, consider disabling debuginfo. This can improve dev build times significantly, by as much as 20-40%.
We're wondering if we should split iterative development from debugging to pull in these improvements (and maybe more). This is being explored at https://github.com/rust-lang/cargo/issues/15931
I have some frontend use cases for rust that I just ended up rewriting in typescript because transferring and loading the wasm rust blob is more expensive than running the program.
I imagine wasm-conscious optimizations would look a lot like targeting microcontrollers, but with weird escape hatches to high-level browser apis.
I got a ton of value from this book. It actually pushed me to dive deeper into profiling and eventually start building Rust perf tooling of my own https://github.com/pawurb/hotpath-rs
12 comments
[ 2.4 ms ] story [ 37.4 ms ] threadSome TILs:
Hashing
> The default hashing algorithm is not specified, but at the time of writing the default is an algorithm called SipHash 1-3. This algorithm is high quality—it provides high protection against collisions—but is relatively slow, particularly for short keys such as integers.
> An attempt to switch from fxhash back to the default hasher resulted in slowdowns ranging from 4-84%!
I/O
> Rust’s print! and println! macros lock stdout on every call. If you have repeated calls to these macros it may be better to lock stdout manually.
Build times
> If you use dev builds but don’t often use a debugger, consider disabling debuginfo. This can improve dev build times significantly, by as much as 20-40%.
Interesting std library alternatives
> If you have many short vectors, you can use the SmallVec type from the smallvec crate. SmallVec<[T; N]> is a drop-in replacement for Vec that can store N elements within the SmallVec itself, and then switches to a heap allocation if the number of elements exceeds that.
> If you have many short vectors and you precisely know their maximum length, ArrayVec from the arrayvec crate is a better choice than SmallVec. It does not require the fallback to heap allocation, which makes it a little faster.
> The SmallString type from the smallstr crate is similar to the SmallVec type.
I doubt I'll change my use of the standard types often, but this is good information to know for cases where this might be applicable.
Advice on enums
> If an enum has an outsized variant, consider boxing one or more fields.
I'm surprised I didn't see any advice about skipping proc macros or Serde for faster compile times.
An interesting thing about the CLR is that the default hash for integers is:
Which as well as being collision-free, also avoids the trap of a slow default hash.The 3rd party library type CompactString can fit up to 24 bytes of UTF-8 text internally, yet it is still the same size as String and just like String, Option<CompactString> is the same size as CompactString. It does add complexity (and of course a library dependency if you care about that) but if you have lots of short strings this may be the best small string type for you.
[The key is UTF-8 encoding can only end with certain bytes, CompactString's documentation explains in more detail]
> I'm surprised I didn't see any advice about skipping proc macros or Serde for faster compile times.
A more comprehensive document on build times is at https://corrode.dev/blog/tips-for-faster-rust-compile-times/
We're integrating parts of it into Cargo's official documentation at https://doc.rust-lang.org/nightly/cargo/guide/build-performa...
We're coordinating the work on that at https://github.com/rust-lang/cargo/issues/16119
> > If you use dev builds but don’t often use a debugger, consider disabling debuginfo. This can improve dev build times significantly, by as much as 20-40%.
We're wondering if we should split iterative development from debugging to pull in these improvements (and maybe more). This is being explored at https://github.com/rust-lang/cargo/issues/15931
Clippy (at least pedantic one) will suggest this if needed.
I have some frontend use cases for rust that I just ended up rewriting in typescript because transferring and loading the wasm rust blob is more expensive than running the program.
I imagine wasm-conscious optimizations would look a lot like targeting microcontrollers, but with weird escape hatches to high-level browser apis.
Though it's archived and seems to be abandoned. And there doesn't seem to be a replacement for it...
https://blog.rust-lang.org/inside-rust/2025/07/21/sunsetting...