What is the most optimised setting when releasing my project?

Hey guys, so if I wanted to officially release my project what would be the best flags I should use (other than using march=native) to acheive maximum application performance, even if it reduced safety?

Please do not use march=native (or the RUSTFLAGS equivalent -Ctarget-cpu=native). The code generated with this option would only be compatible with CPUs that have the same features as the CPU you build on, but not with older CPUs. If you want to support only CPUs with a certain feature set like AVX2, be explicit about it with something like RUSTFLAGS=-Ctarget-feature=+avx2 and inform your users that they need a CPU supporting it.

Besides that I was about to write a lot but the advice on this page is pretty comprehensive: Cheap tricks for high-performance Rust - Pascal’s Scribbles


Keep it mind that binary compiled with this flag may crash(not panic) on some processors. x86[_64] is highly fragmented platform and that's why arch=native improves benchmark result in many cases. Instructions available in the compiler's host machine may not be available in the machine the binary runs, which means the binary contains some illegal instructions.

TBH I don't understand this part. If it's ever possible it would be a compiler bug. It's compiler's duty to not miscompile valid source code. If you want to mimic the optimizing compiler's UB case handling, well, code touching UB is not considered valid so modern compilers usually replace the branch with the fastest code ever imaginable without considering safety - no code. You can replace your main function with literal fn main() {}, but you may not want this.


Yes I don't want to actually use this flag anyways, I wanted to know any other flags.

Thanks I will take a look.

I thought I could disable utf8 checking, out of bounds checking etc?

If you want these, you have to do it explicitly (unsafe { vec.get_unchecked(i) }, etc.). Eliding checking can lead to UB when the conditions are violated, and safe code not having UB is a core tenant of Rust. (Fragmenting the language by having compiler flags that "disable" some UB is an explicit anti-goal as well.)


For testing purposes I will agree having those features is a good thing, but once when everything has been tested, I would want to remove them because doesn't it add overhead to the runtime execution?

Reliability is core tenant of Rust:

Blanket disabling bounds checking would directly contradict that and open the door for security vulnerabilities (and other bugs) you get with C and so on.


You probably haven't tested against all possible inputs that your program might be subjected to, so there's always a possibility that some inputs will be too large, not-UTF8, or have other problematic properties. In specific, performance crtitical places where you've guarded against these situations in some other way, you can use conditional compilation to use unchecked operations in release mode:

if cfg!(debug_assertions) {
} else {
    unsafe { unchecked_version() }

In almost any nontrivial program, “everything has been tested” doesn't happen. The “real world” contains weird (or malicious) cases you don't think of when designing tests, or which are inconvenient to test. For example, tests often work with small input data. What if your program has a bounds-checking bug that manifests when it is given large data?

You also mentioned the example of disabling UTF-8 checking. That would make your program exhibit UB if any input text (files, network messages, command-line arguments, environment variables…) is not UTF-8.

Sure, go ahead and disable your own assertions that are designed to catch particular bugs early, after you've tested those algorithms thoroughly (and please use fuzz testing too — it's easy). But things like bounds checks and UTF-8 checks are keeping the program safe from making false assumptions in actual production use.


Yeah, there aren't really any flags that ignore those safety features across your whole program, and I agree that that wouldn't be a good thing.

For instance, if you just assumed that all input was UTF-8, in a program where, for instance, the user puts in their password or something like that, passing in a non-UTF-8 string to that program could cause undefined behavior, which could open up all kinds of security vulnerabilities that might expose the users password.

I'm sure the user of your program, in that case, would rather wait a few more nano-seconds than they would that their password be compromised.

The issue is that you can't know what your user will put into your program, so anywhere a user is able to influence your program, you have to be careful that the values they input are valid.

There are cases where you, as the programmer, know that an array index is in-bounds or that the string is already valid UTF-8. For instance, you just created the array and set it's length to 4, so you know that 2 is a valid index into that array.

In that case you can choose, on a case-by-case basis to disable the bounds check, but it is unsafe. You are telling Rust "let me do this dangerous thing because I have checked it, don't bother checking it".

Still, honestly, I think it's easy to over-estimate how bad those bounds/UTF-8 checks are for your user.

If you aren't doing something 1 billion times in a row ( depending on what it is, of course ), those checks are never going to be noticed by your user. And Rust is super fast for so many things for "free" anyway. Things like not having a garbage collector makes the execution performance much more predictable and less likely to exhibit noticeable lags.

If you notice that something is not going fast as you want it, then profile the code, measure what is taking the time, and optimize the piece that is actually slowing it down. It probably isn't bounds or UTF-8 checks. In all likelyhood it is something you can optimize with 100% safe rust. This helps you, by preventing you from doing extra work for things that aren't helping your user. And it helps your user by working on things they will actually notice.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.