Does the number of integers differ?

I am working on a project where I do a lot of indexing. I have a few lines, for example:

let mut current_x: usize = (start.x as isize + i as isize * delta_x) as usize; 

start.x and i are usize and delta_x are of type isize . Most of my data does not have a mark, so saving its signatures does not make much sense. On the other hand, when I manipulate an array that I access a lot, I need to convert everything back to usize , as shown above.

Does the number of integers differ? Does it affect runtime performance?

Are there other ways to more easily / more efficiently manage index arithmetic?

+7
rust
source share
1 answer

It depends

In principle, it is impossible to answer your question in isolation. These types of low-level things can be aggressively combined with operations that should happen anyway, so any amount of inlining can change behavior. Also, it depends a lot on your processor; switching to a 64-bit number on an 8-bit microcontroller is probably quite expensive!

My general advice is not to worry. Keep your types consistent, get the right answers, then your code profile and fix the problems you find.

Pragmatically, what are you going to do instead?


However, there are some specific things for x86-64 and Rust 1.18.0.

Same size changing sign

In principle, no impact. If they were built in, then you probably would not even see any assembly.

 #[inline(never)] pub fn signed_to_unsigned(i: isize) -> usize { i as usize } #[inline(never)] pub fn unsigned_to_signed(i: usize) -> isize { i as isize } 

Everyone creates an assembly

 movq %rdi, %rax retq 

Value extension

They must sign or expand the value with zero, so to fill these additional cue bits you need to perform some minimal operation:

 #[inline(never)] pub fn u8_to_u64(i: u8) -> u64 { i as u64 } #[inline(never)] pub fn i8_to_i64(i: i8) -> i64 { i as i64 } 

Generates assembly

 movzbl %dil, %eax retq movsbq %dil, %rax retq 

Value truncation

Truncation is another step, basically no effect.

 #[inline(never)] pub fn u64_to_u8(i: u64) -> u8 { i as u8 } #[inline(never)] pub fn i64_to_i8(i: i64) -> i8 { i as i8 } 

Generates assembly

 movl %edi, %eax retq movl %edi, %eax retq 

All these operations come down to one instruction on x86-64. Then you encounter the complications of “how long does the operation take” and what is even more difficult.

+11
source share

All Articles