> My point was that in many applications memory safety doesn't rank highly as a separate concern, in addition to computing correct output from expected inputIndeed, I was trying to cover that in my comment. I agree that it isn't an explicit selling point to such people, but I think that it should be:
- numerics/scientific computing/machine learning are slowly taking over the world. It is bad to have random/occasional heisenbugs in systems that influence decisions from the personal to the international.
- games are very, very often touching the network these days, and thus are at risk of being exploited by a malicious attacker.
Of course, people in those domains aren't necessarily thinking in those terms/have deadlines to hit/are happy with their current tooling.
> The runtime cost of that approach wasn't obvious to me from the documentation
It is low. I've even heard rumours that the core primitive has the lowest overhead of all similar data parallel constructs, including, say, Cilk. This, combined with aggressive use of "expression templates" (with a special mention to Rust's easily inlinable closures), means I'd be surprised if rayon was noticably slower than OpenMP for the straight-forward map/associative-reduce situations. More exotic transformations are more dubious, given rayon has had far less person-hours put into it.
> it doesn't quite let me keep the loop-based control flow usually employed for numerical calculations (because of the need to refer to different indices within the loop, etc.), but it's certainly a viable approach
I'm not sure loop-based control flow is actually necessary, since (I believe) one can, say, parallelise over an enumerated iterator (e.g. slice.iter().enumerate()), which contains the indices. One can then .map() and read from the appropriate indices as required.
> On the subject of -ffast-math, I did not encounter these recent additions you mention in the language documentation, but I'll take another look on the issue tracker and elsewhere. Thanks for the information.
To shortcut your search: https://doc.rust-lang.org/std/?search=fast . (I apologise that I didn't link it earlier, I was on a phone.)
> On tail call optimisations, I don't believe your statement is entirely correct. It's true that C++ compilers don't guarantee TCO (although, empirically they're very good at it), but Rust doesn't seem to be able to do it at all. It's explicitly stated in the language documentation and there's a recent issue on the subject [1].
I guarantee that rustc can do tail TCO. I've spent a lot of time digging around in its output. The compiler uses LLVM as a back-end, exactly the same as a clang, and things like function calls look the same in C++ and in Rust.
That issue is 5 years old, and closed, and is (implicitly) "teach rust to have away to guarantee TCO", see the mention of 'be' vs. 'ret': they're keywords, 'be' theoretically being used like `be foo(1, 2)` and meaning "this call must be TCO'd" (i.e. my stack frame must be foo's stack frame).
Lastly, if you're talking about the documentation being [0], I think you're misreading it, in particular it says:
> Tail-call optimization may be done in limited circumstances, but is not guaranteed
That said, it is reasonable that you're misreading it, given "Not generally" is being technically correct ("rustc cannot do TCO in complete generality", i.e. there exists at least one tail-call which won't be optimised) in a way that is confusing in normal English. I personally think it would be better if it started with "Yes, but it is not a guarantee" rather than "No".
[0]: https://www.rust-lang.org/en-US/faq.html#does-rust-do-tail-c...
> By the way, is there a way to turn off runtime bounds checking for vectors? That's another common performance sink in numeric computing.
Yes, the get_unchecked and get_unchecked_mut methods. This takes the same approach as the -ffast-math equivalents: disable when required, rather than sacrifice reliability across a whole program. That said, Rust's iterators (which also power rayon) are more idiomatic than manual indexing, when they work, and generally avoid unnecessary bounds checks more reliably.