# Optimization comparison: Vec vs array and for vs while

**URL:** https://internals.rust-lang.org/t/optimization-comparison-vec-vs-array-and-for-vs-while/16410
**Category:** compiler
**Created:** [April 1, 2022, 11:41am UTC](https://internals.rust-lang.org/t/optimization-comparison-vec-vs-array-and-for-vs-while/16410 "2022-04-01T11:41:00Z")
**Posts on this page:** 1
**Showing post:** 3

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [April 1, 2022, 6:02pm UTC](https://internals.rust-lang.org/t/optimization-comparison-vec-vs-array-and-for-vs-while/16410/3 "2022-04-01T18:02:21Z")

</div>

> [@CAD97](#):
>
> adding `let phi = &mut phi[..n + 1];`

"Reslicing" like this is basically always the right thing to do before a bunch of indexing. See this recent post for another example of it: [Mir optimization pass that implements auto-vectorization - #6 by scottmcm](https://internals.rust-lang.org/t/mir-optimization-pass-that-implements-auto-vectorization/16360/6)

And I don't know if it's still true, but at least 1½ years ago it was the case that indexing through `Vec` optimized worse than through a slice ([We all know `iter` is faster than `loop`, but why? - #3 by scottmcm - The Rust Programming Language Forum](https://users.rust-lang.org/t/we-all-know-iter-is-faster-than-loop-but-why/51486/3?u=scottmcm)), which just gives another reason that you should reslice it.

> [@leonardo](#):
>
> for loops are very common and I think they are worth having a more focused optimization

Note that you can opt into more focused optimization for them by changing your `for p in STUFF {` to `STUFF.for_each(|p| {`.

> [@leonardo](#):
>
> ````rust
> let mut i = (n / p - 1) | 1;
> while i > 0 {
> ...
> 
> if i <= 2 { break; }
> i -= 2;
> }```
> 
> ````

This loop is kinda weird, BTW.

_Anything_ `| 1` will be `> 0`, and you break at the bottom before `i` can get down to `0`.

So I think it should be a `loop`?

But more importantly, I think you can reduce this report down to something more specific, by asking whether LLVM more directly whether it knows certain things.

For example, I'm extra confident about the `while` condition because if you ask LLVM to compile

```rust
pub fn demo_lower(n: usize, p: usize) -> bool {
    assert!(p >= 3);

    let i = (n / p - 1) | 1;
    i > 0
}

```

the output is clearly "oh yeah, that either asserts or returns true".

Whereas if you ask it about

```rust
pub fn demo_upper(n: usize, p: usize) -> bool {
    assert!(p >= 3);

    let i = (n / p - 1) | 1;
    i < (n + 1)
}

```

Then it obviously has no idea

```llvm
define noundef zeroext i1 @_ZN7example10demo_upper17hed0063195a0d922bE(i64 %n, i64 %p) unnamed_addr #0 !dbg !13 {
  %_4 = icmp ult i64 %p, 3, !dbg !14
  br i1 %_4, label %bb1, label %bb3, !dbg !15

bb1: ; preds = %start
  tail call void @_ZN4core9panicking5panic17hef60c19188bfa7ddE([0 x i8]* noalias noundef nonnull readonly align 1 bitcast (<{ [24 x i8] }>* @alloc14 to [0 x i8]*), i64 24, %"core::panic::location::Location"* noalias noundef readonly align 8 dereferenceable(24) bitcast (<{ i8*, [16 x i8] }>* @alloc16 to %"core::panic::location::Location"*)) #2, !dbg !15
  unreachable, !dbg !15

bb3: ; preds = %start
  %_8 = udiv i64 %n, %p, !dbg !16
  %_7 = add nsw i64 %_8, -1, !dbg !17
  %i = or i64 %_7, 1, !dbg !17
  %_13 = add i64 %n, 1, !dbg !18
  %0 = icmp ult i64 %i, %_13, !dbg !20
  ret i1 %0, !dbg !21
}

```

And thus the problem _isn't_ that it doesn't know the bounds, it's that regardless of whether it knows the vec/slice bound or not, the indexing logic you're using is too complicated for it to figure out.

So you might consider other ways to write that logic that it might understand better, or consider [filing an LLVM issue](https://github.com/llvm/llvm-project/issues/new) about it if you think that LLVM should understand what you're doing.

(Repro for those two snippits: [https://rust.godbolt.org/z/qYcnM1E5G](https://rust.godbolt.org/z/qYcnM1E5G))

---

_[View the full topic](https://internals.rust-lang.org/t/optimization-comparison-vec-vs-array-and-for-vs-while/16410)._
