Simplify this code:

Is there a better way to write:

            out[idx + 0] = lhs_bytes[0];
            out[idx + 1] = lhs_bytes[1];
            out[idx + 2] = lhs_bytes[2];
            out[idx + 3] = lhs_bytes[3];

here out: &mut [u8] and lhs_bytes: [u8; 4]

out[idx..idx+4].copy_from_slice(&lhs_bytes)

?

6 Likes

Does this incur a for loop and branching? I'm slightly surprised there isn't a simple way to directly assign a [u8; 4].

optimizing compilers are pretty impressive these days. you should check the assembly output to get a useful answer to that question.

2 Likes

Both versions of the code require branching to check whether the indices are in range. In many contexts this could be optimized, but that would require that you provide a larger context of how this code is used.

@geeklint's version is somewhat better optimized by the compiler than the original code, because the original generates 4 branches in between moving bytes while @geeklint's code generates 2 branches and then moves all 4 bytes in one go:

The compiler could be smarter about the original code, but isn't. There is a ticket for this:

1 Like

You could write this:

pub fn code3(out: &mut [u8], vals: [u8; 4], idx: usize) {
    *<&mut [u8; 4]>::try_from(&mut out[idx..idx+4]).unwrap() = vals;
}

It compiles down to exactly the same as the copy_from_slice version though.

5 Likes

Exactly what the "get arrays from a slice" methods are going to be is still up in the air. If you're willing to try out nightly things, you could give feedback in the tracking issues for things like https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_chunks_mut and
https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_array_ref and
Add slice::{split_,}{first,last}_chunk{,_mut} by clarfonthey · Pull Request #95198 · rust-lang/rust · GitHub.

YMMV, but you can also write that as out[idx..][..4], which I tend to prefer since it makes the "it'll end up 4 elements long" blatantly obvious, and means I don't have to think about overflow.

4 Likes