Optimization Rust是否在计算范围内优化回路?

Optimization Rust是否在计算范围内优化回路?,optimization,rust,micro-optimization,Optimization,Rust,Micro Optimization,作为练习,我正在尝试对Rust 1.3.0中的代码进行微优化。我有一个数组上的循环。大概是这样的: loop { for i in 0..arr.len() { // something happens here } } 由于数组的大小在Rust中是固定的,编译器会通过只计算一次并重用值来优化代码吗?还是会在每次通过顶级循环时对表达式进行计算?除了arr.len()之外,这个问题可以扩展到计算量更大的函数,而不会产生副作用 换言之,上述代码是否等同于: let

作为练习,我正在尝试对Rust 1.3.0中的代码进行微优化。我有一个数组上的循环。大概是这样的:

loop {
    for i in 0..arr.len() {
        // something happens here
    }
}
由于数组的大小在Rust中是固定的,编译器会通过只计算一次并重用值来优化代码吗?还是会在每次通过顶级循环时对表达式进行计算?除了
arr.len()
之外,这个问题可以扩展到计算量更大的函数,而不会产生副作用

换言之,上述代码是否等同于:

let arr_len = arr.len();

loop {
    for i in 0..arr_len {
        // something happens here
    }
}

至少在使用嵌套在另一个循环中的
arr.len()
进行快速检查时,似乎根本没有为
arr.len()的“调用”生成代码。在生成的代码中,数组的大小只是硬编码到输出中


换句话说,我不希望您的第二个代码段的执行速度比第一个快。

至少在使用嵌套在另一个循环中的
arr.len()
进行快速检查时,似乎根本没有为
arr.len()
的“调用”生成代码。在生成的代码中,数组的大小只是硬编码到输出中


换句话说,我不希望第二个代码段的执行速度比第一个快。

the
是一个范围运算符,它形成一个对象(或派生对象:
RangeFrom
RangeFull
RangeTo
)。这些对象只包含索引(Idx类型),因此您可以放心,
.len()
只计算一次


通常,检查LLVM IR是一个好主意。如果你有一个合成的例子,你可以很容易地使用操场。用于:

生成以下函数:

; Function Attrs: uwtable
define internal void @_ZN4main20hd87dea49c835fe43laaE() unnamed_addr #1 {
entry-block:
  tail call void @doit(i32 1)
  tail call void @doit(i32 2)
  tail call void @doit(i32 3)
  tail call void @doit(i32 4)
  tail call void @doit(i32 5)
  ret void
}

在这种情况下,对于固定长度,根本没有循环:它已展开。

是一个范围运算符,它形成一个对象(或派生对象:
RangeFrom
RangeFull
RangeTo
)。这些对象只包含索引(Idx类型),因此您可以放心,
.len()
只计算一次


通常,检查LLVM IR是一个好主意。如果你有一个合成的例子,你可以很容易地使用操场。用于:

生成以下函数:

; Function Attrs: uwtable
define internal void @_ZN4main20hd87dea49c835fe43laaE() unnamed_addr #1 {
entry-block:
  tail call void @doit(i32 1)
  tail call void @doit(i32 2)
  tail call void @doit(i32 3)
  tail call void @doit(i32 4)
  tail call void @doit(i32 5)
  ret void
}

在这种情况下,对于固定长度,根本没有循环:它已展开。

请注意,如果您对优化感兴趣,通常最好尝试使用迭代器,而不是索引到切片中,这会给边界检查带来一些开销。在可能的情况下,对v in&arr使用
。请注意,如果您对优化感兴趣,通常最好尝试使用迭代器,而不是索引到切片中,这会给边界检查带来一些开销。如果可能,请使用
for v in&arr
。我认为OP指的是整个for循环体的多个执行,而您正在处理(如果我错了,请纠正我)for循环单个执行的迭代。换句话说,他想知道,每次for循环开始时,是否会再次计算范围范围,即使它们不能更改(因为数组长度不能更改)。请注意,他的for循环嵌套在另一个循环中。@BenjaminLindley是的,这正是我的意思。我认为OP指的是整个for循环体的多个执行,而您指的是(如果我错了,请纠正我)for循环单次执行的迭代。换句话说,他想知道,每次for循环开始时,是否会再次计算范围范围,即使它们不能更改(因为数组长度不能更改)。请注意,他的for循环嵌套在另一个循环中。@BenjaminLindley是的,这正是我的意思。这基本上与我在编辑之前针对Benjamin Lindley的评论所做的回答相似。@JerryCoffin:恐怕我从未见过你答案的前一个版本:/这与我在编辑之前的回答基本相似,作为对本杰明·林德利评论的回应。@JerryCoffin:恐怕我从未见过你回答的前一个版本:/