我正在进行一项项目,我正在进行大量基于索引的计算.我有几行像:
let mut current_x: usize = (start.x as isize + i as isize * delta_x) as usize;
Run Code Online (Sandbox Code Playgroud)
start.x并且i是usizes和delta_x类型isize.我的大多数数据都是无符号的,因此将其签名存储没有多大意义.另一方面,当我操作一个数组时,我正在访问很多,我必须将所有内容转换回来,usize如上所示.
整数之间的铸造是否昂贵?它对运行时性能有影响吗?
还有其他方法可以更轻松/更有效地处理索引算术吗?
She*_*ter 13
这取决于
基本上不可能孤立地回答你的问题.这些类型的低级事物可以积极地与必须发生的操作相结合,因此任何数量的内联都可以改变行为.此外,它很大程度上取决于您的处理器; 在8位微控制器上更改为64位数字可能相当昂贵!
我的一般建议是不要担心.保持您的类型一致,获得正确的答案,然后分析您的代码并解决您发现的问题.
从务实角度来说,你有什么打算做的,而不是?
也就是说,这是x86-64和Rust 1.18.0的一些具体内容.
基本上没有影响.如果这些是内联的,那么你可能永远不会看到任何组装.
#[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
}
Run Code Online (Sandbox Code Playgroud)
每个都生成组件
movq %rdi, %rax
retq
Run Code Online (Sandbox Code Playgroud)
这些必须对值进行符号或零扩展,因此必须进行某种最小化操作来填充这些额外的位:
#[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
}
Run Code Online (Sandbox Code Playgroud)
生成程序集
movzbl %dil, %eax
retq
movsbq %dil, %rax
retq
Run Code Online (Sandbox Code Playgroud)
截断再次只是另一个举动,基本上没有影响.
#[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
}
Run Code Online (Sandbox Code Playgroud)
生成程序集
movl %edi, %eax
retq
movl %edi, %eax
retq
Run Code Online (Sandbox Code Playgroud)
所有这些操作归结为x86-64上的单个指令.然后你会遇到"手术需要多长时间"的复杂情况,而且更难.
| 归档时间: |
|
| 查看次数: |
719 次 |
| 最近记录: |