Picture of enum_dispatch


Published December 13, 2018

Rust is an amazingly expressive programming language that allows developers to build really fast applications. The Rust compiler is generally able to optimize code written without any extra consideration for performance, but there are a few instances where that's not possible. Dynamic dispatch is one feature that can make code easier to write, but harder to optimize.

In short, Rust code using dyn Trait forces virtual table lookups to determine types at runtime, and prevents the compiler from aggressive optimizations like inlining or removing unreachable branches. I didn't have to figure this out myself - it's a well-known phenomenon that applies to other compiled languages with opaque traits or interfaces as well.

If your code handles a lot of dyn Trait objects, especially in loops, you could get a significant performance increase by switching them to use static dispatch instead. In practice, that involves wrapping all possible Trait implementors into an enum definition, implementing Trait for that enum by forwarding each method call to the inner type, and then constructing an instance of that enum around every instance of a Trait implementor.

That takes a lot of code! That's why I wrote enum_dispatch, which is a Rust procedural macro library that makes it easy to gain up to 10x performance on dynamic dispatched method calls while keeping boilerplate to a minimum. Not convinced? Check out this commit I found in the wild, demonstrating how much repetitive code you can get rid of.

enum_dispatch is by far my most successful personal project, with well over 1 million downloads on crates.io. I've heard of it being used in important codebases at several large companies, there's a whole bunch of cool dependent crates on crates.io, and even more fun projects I've found just by searching on GitHub. It's also been selected as Crate of the Week.

If enum_dispatch sounds useful to you, check out the README to see how you can get started with it!