5 ms·
Not every platform has a branch predictor, like low-cost embedded platforms, where bare metal languages like C++ are commonly used. Error-case performance is n
by softc 10y ago
Not every platform has a branch predictor, like low-cost embedded platforms, where bare metal languages like C++ are commonly used.
Error-case performance is negligible as it's much more rare (cf. Amdahl's law). If errors are common in a specific section of code, in C++ you have the option of using simple error-checking. You have no such counter-option in Rust.
- akiselev 10y ago> Not every platform has a branch predictor, like low-cost embedded platforms, where bare metal languages like C++ are commonly used. You're moving the goal posts. Itanium processors do have branch prediction so comparing C++ exceptions on Itanium to Rust on embedded architectures is meaningless. In embedded Rust, the worst case scenario is a compare between a constant and a register or a byte on the stack. Most non-ARM embedded platforms I've written firmware for barely have a three cycle multiply so a one cycle compare will be negligible except in the most extreme of cases (where you'd just write inline assembly anyway, no matter the language). On those platforms, you spend more time restoring registers than comparing the result of a call. On ARM processors, conditional execution behaves like a branch predictor on short compare jumps so there's again no overhead (except with value types, in which case Option adds 1-4 bytes for the None case on the stack). Either way, Rust's error checking overhead is irrelevant. If your embedded environment is so resource constrained that Rust's error checking is too much overhead for you, then you certainly can't use C++ exceptions. They are too unpredictable without prohibitively expensive physical testing and tedious tuning of worst case code paths (unless you don't care about hard real time guarantees at all). If it's not, then it doesn't matter whether you use Rust errors or C++ exceptions because the overhead is a rounding error. We're not talking about something like reading memory from cache vs RAM or static vs dynamic dispatch where the difference in performance can be 10-1000x, we're literally talking about single digit cycles here. > If errors are common in a specific section of code, in C++ you have the option of using simple error-checking. You have no such counter-option in Rust. Yes, you do. You can unwind the stack manually and jump to the error handler, just like the C++ compiler does for you with exceptions. This is how the panic macro is implemented so all you have to do is modify its implementation (compiler-builtins crate) and create your own catch_unwind function. With the amount of time you'd spend typing "if (result != null)" or implementing an option type in C++, you can write your own exception implementation using Rust macros and traits. Rust developers made the right decision: "simple" error checking is the default with syntactic sugar to ease its use and if you really need those few extra cycles, you can make your own crate or compiler plugin that will give you the same features without polluting the rest of the ecosystem with a default error handling mechanism that is opaque, complex, and unsuitable for resource constrained real time systems.
- softc 10y agoThe Itanium ABI is basically the reference ABI for all platforms, it doesn't only apply to Itanium. Rust's error checking overhead is not unanimously irrelevant, it's not uncommon for functions to be called in tight loops. I won't address your other comments since they are subjective and/or dependent on circumstances.