Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I use direct access into a Rust Vec instead of the get method?

Tags:

rust

Rust supports two methods for accessing the elements of a vector:

let mut v = vec![1, 2, 3];

let first_element = &v[0];

let second_element = v.get(1);

The get() method returns an Option type, which seems like a useful safety feature. The C-like syntax &v[0] seems shorter to type, but gives up the safety benefits, since invalid reads cause a run-time error rather than producing an indication that the read was out of bounds.

It's not clear to me when I would want to use the direct access approach, because it seems like the only advantage is that it's quicker to type (I save 3 characters). Is there some other advantage (perhaps a speedup?) that I'm not seeing? I guess I would save the conditional of a match expression, but that doesn't seem like it offers much benefit compared to the costs.

like image 216
John Doucette Avatar asked Aug 17 '18 16:08

John Doucette


People also ask

What is Vec <_> Rust?

It means "Rust compiler, infer what type goes into the Vec ". And it is indeed analogous to the unused variable in Python (and in Rust itself), in that it represents a placeholder for a type, like it can represent a placeholder for a variable name.

How do you initialize VEC in Rust?

In Rust, there are several ways to initialize a vector. In order to initialize a vector via the new() method call, we use the double colon operator: let mut vec = Vec::new();

How do you clear a vector in Rust?

To remove all elements from a vector in Rust, use . retain() method to keep all elements the do not match. let mut v = vec![ "A", "warm", "fall", "warm", "day"]; let elem = "warm"; // element to remove v.


1 Answers

Neither of them is quicker because they both do bounds checks. In fact, your question is quite generic because there are other pairs of methods where one of them panics while the other returns an option, such as String::reserve vs String::try_reserve.

  • If you are sure that you are in bounds, use the brackets version. This is only a syntactic shortcut for get().unwrap().
  • If you are unsure of this, use the get() method and do your check.
  • If you critically need maximum speed and you cannot use an iterator and you have determined through benchmarks that the indexing is the bottleneck and you are sure to be in bounds, you can use the get_unchecked() method. Be careful about this because it is unsafe: it is always better to not have any unsafe block in your code.

Just a little bit of advice: if you are concerned by your program performance, avoid using those methods and prefer to use iterators as much as you can. For example, the second example is faster than the first one because in the first case there are one million bounds checks:

let v: Vec<_> = (0..1000_000).collect();

for idx in 0..1000_000 {
    // do something with v[idx]
}

for num in &v {
    // do something with num
}
like image 86
Boiethios Avatar answered Nov 15 '22 09:11

Boiethios