Live data from Hacker News

How much does Rust's bounds checking cost?

blog.readyset.io

71–80 of 195 posts

Re: How much does Rust's bounds checking cost?

#71
post #44

Earlier quoted context omitted.

I don't think that's always possible in practice: consider Vec , whose size is only known at runtime. A Vec 's iterator can only do runtime bounds checking to avoid walking past the end. That said, this is unavoidable in C/C++ too.

I think we're suffering from some fuzziness about what bounds checks we're referring to. Even in your example, you only need to check the size of the Vec when you instantiate the iterator, not each time the iterator accesses an element, because at the time the iterator over the Vec 's contents is instantiated, the Vec 's size is known, and it can't change over the life of the iterator (because mutation is disallowed…

When I read "iterator" I think of an object that points into the vector and can be advanced. For Rust's vector, that is std::slice::Iter (https://doc.rust-lang.org/std/slice/struct.Iter.html). When you advance an iterator, you must do a bounds check if the vector is dynamically sized; otherwise, you don't know when to stop. I.e., if I have

  let mut it = vec.iter();
  println!(it.next());
  println!(it.next());
  println!(it.next());
This needs to do bounds checking on each call to next() to either return Some(a) or None (assuming the length of vec is unknown at compile time). (hhttps://doc.rust-lang.org/beta/src/core/slice/iter/macros.rs....)

You are right that theoretically a range-based for loop that uses iterators does not need to do bounds checking because a compiler can infer the invariant that the iterator is always valid. In practice I don't know enough about LLVM or rustc to know whether this optimization is actually happening.

Re: How much does Rust's bounds checking cost?

#72

I've been shocked when I've heard C programmers being actually concerned about performance penalty of checks like, why bother? CPUs in next 2 years will win that performance anyway and your software will be safer

Most online debates are filled with illogical opinions on theoretical issues. You get people on this site complaining that they have to spend money on a catalytic converter because it's not required for the car to run and only prevents other people from getting cancer.

Re: How much does Rust's bounds checking cost?

#73
post #66

One technique is to add asserts before a block of code to hoist the checks out. The compiler is usually smart enough to know which conditions have already been checked. Here's a simple example: https://rust.godbolt.org/z/GPMcYd371 This can make a big difference if you can hoist bounds checks out of an inner loop. You get the performance without adding any unsafe {}.

[deleted]

Re: How much does Rust's bounds checking cost?

#74
post #44

Earlier quoted context omitted.

In Rust at least, once you instantiate the iterator, the array it's iterating over can't be mutated until the iterator is dropped, and that can be statically guaranteed at compile time. So you don't need to bounds-check at every access; you can decide at the outset how many iterations there are going to be, and doing that number of iterations will be known not to walk past the end.

I don't think that's always possible in practice: consider Vec , whose size is only known at runtime. A Vec 's iterator can only do runtime bounds checking to avoid walking past the end. That said, this is unavoidable in C/C++ too.

What parent means is that you won't have any bound checks on array access, just a len(arr) loop.

Re: How much does Rust's bounds checking cost?

#75
post #64
post #49

The reason performance decreased when he removed bounds checking is because asserting bounds is very useful to a compiler. Essentially, the compiler emits code like this: 1. if (x >= 0) && (x The compiler deduces that at line 5 0 1. get element from array index x 2. do more stuff So the compiler doesn't know anything about x, which is bad. The solution which apparently is not implemented in Rust (or LLVM, idk) is to…

I'm not sure I follow: where is abs(x)?

It’s an example of what could occur within “do more stuff”. The mentioned 2*x is another example.

Re: How much does Rust's bounds checking cost?

#76

Earlier quoted context omitted.

The 5ms isn't the key number. It's 5ms extra over a 28ms baseline, that's about 18% difference. If your noise threshold is 18%, then I think you have to accept that the benchmark probably isn't any good for this stated task.

https://github.com/bheisler/criterion.rs is good for tests like that. It will give you much more than a single number and handle things like outliers. This makes identifying noisy tests simpler.

The benchmarking harness that the post uses is based on criterion

Re: How much does Rust's bounds checking cost?

#77
post #62
post #45

Always amuses me that it's current year and people think about turning off checks, even when they're pretty much free in modern* (since 1993 Pentium, which got like 80% accuracy with its primitive branch prediction?) CPUs... "Around Easter 1961, a course on ALGOL 60 was offered … After the ALGOL course in Brighton, Roger Cook was driving me and my colleagues back to London when he suddenly asked, "Instead of designin…

> I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary precautions would have long been against the law. Here we are, 42 years later, and bounds checks are still not the default in some languages. Because performance, or something. And our computers are literally 1000x as fast as they were…

Removing bounds checks is a stark example of a premature optimization.

You can remove bounds checks when you can prove that the index won't ever get out of bounds; this is possible in many cases, such as iteration with known bounds.

Re: How much does Rust's bounds checking cost?

#78
post #45

Always amuses me that it's current year and people think about turning off checks, even when they're pretty much free in modern* (since 1993 Pentium, which got like 80% accuracy with its primitive branch prediction?) CPUs... "Around Easter 1961, a course on ALGOL 60 was offered … After the ALGOL course in Brighton, Roger Cook was driving me and my colleagues back to London when he suddenly asked, "Instead of designin…

They’re nowhere near free. Branch prediction table has finite entries, instruction cache has finite size, autovectorizing is broken by bounds checks, inlining (the most important optimization) doesn’t trigger if functions are too big because of the added bounds checking code, etc. This is just not great benchmarking — no effort to control for noise.

Re: How much does Rust's bounds checking cost?

#79

Earlier quoted context omitted.

a 10% drop in performance with bounds checks removed , mind you - so if anything the bounds checks are improving performance.

The more likely explanation is that the test is bunk. Or maybe the unsafe access acts like volatile in C and disables any optimization/reordering because the compiler thinks it’s accessing a register.

Unsafe accesses do not act that way, they compile to exactly the same code as array accesses in C.

The tests aren't bunk. There are a variety of reasons why the assertions generated by array index checks can be useful for LLVM, and there is also a fair amount of noise in any end to end test like this. The main point is that it clearly isn't a primary bottleneck (which should be pretty obvious in a test that takes 30 ms and performs under 2000 bounds checks).

Re: How much does Rust's bounds checking cost?

#80

What if a compiler were to only allow an array access when it can prove that it's in bounds? Wherever it can't you'd have to wrap the array access in an if, or otherwise refactor your code to help the compiler. Then you'd have no panicking at least and more predictable performance.

That's how WUFFS (Wrangling Untrusted File Formats Safely) works: https://github.com/google/wuffs#what-does-compile-time-check...

WUFFS is awesome. It won't even let you add two ints without proving they cannot overflow
Post reply on HN