# Optimizing by default

**URL:** <https://internals.rust-lang.org/t/optimizing-by-default/1532>\
**Category:** internals\
**Created:** [February 4, 2015, 12:41am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532 "2015-02-04T00:41:05Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![Valloric](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/valloric/32/9611_2.png) [@Valloric](https://internals.rust-lang.org/u/Valloric)\
**Post date:** [February 15, 2015, 10:49pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/21 "2015-02-15T22:49:53Z")

</div>

[Another example](http://www.reddit.com/r/rust/comments/2vzxjr/poor_http_performance_iron_framework/) of a Rust user being bitten by “unoptimized by default.”

---

<div class="post-metadata">

**Author:** ![tbu](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tbu](https://internals.rust-lang.org/u/tbu)\
**Post date:** [February 16, 2015, 12:09am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/22 "2015-02-16T00:09:34Z")

</div>

There’s also people complaining about long compile times, and this might increase if we change it to “optimized by default”.

---

<div class="post-metadata">

**Author:** ![tanadeau](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tanadeau/32/5419_2.png) [@tanadeau](https://internals.rust-lang.org/u/tanadeau)\
**Post date:** [February 16, 2015, 12:50am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/23 "2015-02-16T00:50:38Z")

</div>

Thanks for the example, @Valloric. I added it to the Cargo issue.

---

<div class="post-metadata">

**Author:** ![tomjakubowski](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tomjakubowski/32/4876_2.png) [@tomjakubowski](https://internals.rust-lang.org/u/tomjakubowski)\
**Post date:** [February 16, 2015, 3:10am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/24 "2015-02-16T03:10:44Z")

</div>

An alternative (for Cargo users anyway) would be to nag users when running “cargo build” that they are building an unoptimized binary and suggest using the “–release” flag before testing performance. There would also be a message indicating a cargo command to run that will disable the nag message (by writing to the Cargo config file)

---

<div class="post-metadata">

**Author:** ![tanadeau](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tanadeau/32/5419_2.png) [@tanadeau](https://internals.rust-lang.org/u/tanadeau)\
**Post date:** [February 16, 2015, 3:27am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/25 "2015-02-16T03:27:14Z")

</div>

@tomjakubowski Yep, I created a [Cargo issue](https://github.com/rust-lang/cargo/issues/1309) to do that. If you agree with it, please comment on it and +1 it.

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [February 16, 2015, 5:25pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/26 "2015-02-16T17:25:38Z")

</div>

I’ll admit that I myself got bit by debug-by-default when I first got started with Rust, but that was before `cargo` was a thing. `cargo bench` implies optimizations, and therefore would have protected me from my mistake.

As such I’m a bit torn. I feel like there’s a reasonable motivation to be had on both sides. I guess lacking optimization is the bigger foot-gun than having optimization when you don’t care. Although missing debug asserts or debug info is presumably not great?

---

<div class="post-metadata">

**Author:** ![Valloric](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/valloric/32/9611_2.png) [@Valloric](https://internals.rust-lang.org/u/Valloric)\
**Post date:** [February 16, 2015, 6:09pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/27 "2015-02-16T18:09:43Z")

</div>

> [@Gankra](#):
>
> I'll admit that I myself got bit by debug-by-default when I first got started with Rust, but that was before cargo was a thing. cargo bench implies optimizations, and therefore would have protected me from my mistake.

People evaluating Rust are unlikely to know about `cargo`; even if they will, they won't know about `cargo bench`.

> [@Gankra](#):
>
> I guess lacking optimization is the bigger foot-gun than having optimization when you don't care. Although missing debug asserts or debug info is presumably not great?

If you compile without debug symbols and need them, you'll immediately notice you don't have them. Since the user explicitly needs debug symbols, they'll know they need to look at how to get a debug build.

If you need perf, you'll just notice that "Rust is slow." If you come from any of the Big 5 languages I listed previously (and you are certainly likely to), the thought that a magic compiler flag is needed to get any real perf will never even cross your mind.

Debug-by-default is just a poor design, period. It's a footgun of massive proportions. Rust is already breaking with programming convention in a myriad ways to eliminate footguns (which is _excellent_); it should break with convention here as well.

**Let's not leave footguns in place because of obsolete conventions created by backwards compatibility decisions made 40 years ago.**

---

<div class="post-metadata">

**Author:** ![tbu](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tbu](https://internals.rust-lang.org/u/tbu)\
**Post date:** [February 16, 2015, 8:05pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/28 "2015-02-16T20:05:58Z")

</div>

> [@Valloric](#):
>
> People evaluating Rust are unlikely to know about cargo;

Don't think so, it's advertised all over the tutorials, it's usually assumed that you want to have it over plain rustc, even.

---

<div class="post-metadata">

**Author:** ![tbu](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tbu](https://internals.rust-lang.org/u/tbu)\
**Post date:** [February 16, 2015, 8:08pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/29 "2015-02-16T20:08:06Z")

</div>

> [@Valloric](#):
>
> Debug-by-default is just a poor design, period. It's a footgun of massive proportions.

It's not a poor design, "period". Please be willing to listen to counter arguments.

---

<div class="post-metadata">

**Author:** ![tbu](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tbu](https://internals.rust-lang.org/u/tbu)\
**Post date:** [February 16, 2015, 8:09pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/30 "2015-02-16T20:09:27Z")

</div>

> [@Valloric](#):
>
> Let's not leave footguns in place because of obsolete conventions created by backwards compatibility decisions made 40 years a

Sorry for triple reply, but this particular sentence is just rethorics, let's leave that behind and focus on arguments only. Thanks.

---

<div class="post-metadata">

**Author:** ![hauleth](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hauleth/32/1322_2.png) [@hauleth](https://internals.rust-lang.org/u/hauleth)\
**Post date:** [February 16, 2015, 11:54pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/31 "2015-02-16T23:54:32Z")

</div>

👍 for enabling optimisations by default.

Especially when for any project bigger than 1 file there is Cargo. In most cases when `rustc` will be ran “manually” it is learning, micro-benchmarking or PoC. Anyone that works on 3rd option seriously don’t give a s… about performance, but first 2 options are most important for us. IMHO most of micro-benchmarks will be written by haters and others that will only want to show that “Rust is bad” and someone who is still learning will see if (s)he cannot debug program and will add appreciated flags (or at least will ask how to debug and do not say that “Rust is s… because it runs 99999x slower than XYZ”).

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [February 17, 2015, 3:33am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/32 "2015-02-17T03:33:41Z")

</div>

You won’t know if you’re missing debug\_asserts, but I suppose those are more important in a language like C++ where so much is UB, and debug\_asserts really save you. In Rust most of our debug\_asserts are internal sanity checks against the implementation, and not things that are actually guarding against bad user code.

I have been hoping to toss some debug\_asserts in some of our _unsafe_ APIs, though. e.g. maybe get\_unchecked _is still checked_ in debug builds. Using unsafe code should be considered moderately “advanced” though.

Although debug\_asserts are actual disjoint from _optimization_. They’re tied to the ndebug flag. So you can compile in O3 with ndebug=false (which I believe is basically what the nightlies do?). Presumably you are proposing also passing ndebug=true as well by default?

---

<div class="post-metadata">

**Author:** ![cmr](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cmr/32/5_2.png) [@cmr](https://internals.rust-lang.org/u/cmr)\
**Post date:** [February 17, 2015, 3:56am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/33 "2015-02-17T03:56:58Z")

</div>

There’s a big difference between a _release build_, and just building with optimizations. I do believe building with optimizations by default is the ideal behavior, but those debug asserts _really_ ought not go away until the final build that will be distributed. Tests should still run on debug builds; those asserts are what find your bugs!

---

<div class="post-metadata">

**Author:** ![tanadeau](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tanadeau/32/5419_2.png) [@tanadeau](https://internals.rust-lang.org/u/tanadeau)\
**Post date:** [February 17, 2015, 4:13am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/34 "2015-02-17T04:13:14Z")

</div>

I agree that debug/release isn’t a strict binary. Optimizing with assertions on seems like a good default behavior. Full release builds are for benchmarking and deployment.

---

<div class="post-metadata">

**Author:** ![tanadeau](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tanadeau/32/5419_2.png) [@tanadeau](https://internals.rust-lang.org/u/tanadeau)\
**Post date:** [February 17, 2015, 4:16am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/35 "2015-02-17T04:16:32Z")

</div>

@Gankro, speaking of `ndebug`, do you know why Rust kept the same strange negated boolean name as C++? `debug=true` or `debug=false` seems so much simpler.

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [February 17, 2015, 4:17am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/36 "2015-02-17T04:17:54Z")

</div>

Compiler flags are totally adhoc right now, as far as I know. Haven’t been stabilized/reviewed at all.

---

<div class="post-metadata">

**Author:** ![tanadeau](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tanadeau/32/5419_2.png) [@tanadeau](https://internals.rust-lang.org/u/tanadeau)\
**Post date:** [February 17, 2015, 4:23am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/37 "2015-02-17T04:23:53Z")

</div>

Thanks. I’ll take a look and see if there’s already an issue for that. I’d like to get into the Rust code, and that seems like it would be an easy task.

Another thing still to consider is the integer overflow behavior. Currently/before 1.0 the plan is only to have integer overflow or underflow detection in “debug” builds. If we change the default to optimize but keep debug behavior, does the overflow checking stay on? It seems reasonable that it should, but that code generation can prevent a lot of peephole optimizations due to the jump. It would definitely hurt the performance of numerics-heavy code.

---

<div class="post-metadata">

**Author:** ![cmr](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cmr/32/5_2.png) [@cmr](https://internals.rust-lang.org/u/cmr)\
**Post date:** [February 17, 2015, 4:38am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/38 "2015-02-17T04:38:18Z")

</div>

There is a great document somewhere describing the different build types, the C committee’s opinion on them, and why `NDEBUG` is the correct choice, but I can’t seem to find it right now ☹

---

<div class="post-metadata">

**Author:** ![dhardy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhardy/32/2399_2.png) [@dhardy](https://internals.rust-lang.org/u/dhardy)\
**Post date:** [February 17, 2015, 11:18am UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/39 "2015-02-17T11:18:20Z")

</div>

`#ifndef NDEBUG ...` is used in C because it means that if there is a typo in the macro name or somebody forgot about it, the section is turned on (which usually means assertions enabled). The first reason doesn’t apply to Rust code because the compiler will tell you if the macro names are wrong.

Optimisation levels: are there only two (on/off)? GCC supports many (extracts from man page):

```
With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.

-O2 Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. As compared to -O, this option increases both compilation time and the performance of the generated code.

-O3 Optimize yet more.

-O0 Reduce compilation time and make debugging produce the expected results. This is the default.

-Os Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.

```

As noted here, disabling optimisations can be useful to reduce compilation time and to make code behave in a more expected manner when run in a debugger. _This implies that under specific circumstances disabling optimisations is useful, but not that this needs to be the default._

From my point of view, an optimisation level equivalent to `-O1` or `-O2` would be a good default. (Not `-O3` because some of those optimisations result in numeric approximations or in some cases, significantly larger code size and maybe other draw-backs.)

---

<div class="post-metadata">

**Author:** ![ahmedcharles](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ahmedcharles/32/4041_2.png) [@ahmedcharles](https://internals.rust-lang.org/u/ahmedcharles)\
**Post date:** [February 18, 2015, 7:25pm UTC](https://internals.rust-lang.org/t/optimizing-by-default/1532/40 "2015-02-18T19:25:47Z")

</div>

I agree with optimizing by default for rustc, at least, since by the time you need to debug anything, you already know (or will rapidly learn) how to turn optimizations off. For cargo it’s harder to say since I don’t want to have to type significantly more when developing to get a debug build rather than a release one. But that could be fixed by adding a marker in Cargo.toml which specifies what the default is for a simple cargo build and let the user decide.

[Previous page](https://internals.rust-lang.org/t/optimizing-by-default/1532.md?page=1)

[Next page](https://internals.rust-lang.org/t/optimizing-by-default/1532.md?page=3)
