Rust 对于向量类型,高效实现Add特征的首选方法是什么
Add特征定义为 当为向量实现它时,需要将其复制到add方法中,以允许类似v1+v2的语法。如果将add实现更改为支持借用引用,从而阻止复制,则必须写入&v1+&v2,这是不可取的 这样做的首选或最佳方式是什么 <>在C++中,自会是const向量,以及RHS,但仍然允许所需的v1+v2语义。 代码 为了完整起见,我现在使用的代码摘录Rust 对于向量类型,高效实现Add特征的首选方法是什么,rust,Rust,Add特征定义为 当为向量实现它时,需要将其复制到add方法中,以允许类似v1+v2的语法。如果将add实现更改为支持借用引用,从而阻止复制,则必须写入&v1+&v2,这是不可取的 这样做的首选或最佳方式是什么 在C++中,自会是const向量,以及RHS,但仍然允许所需的v1+v2语义。 代码 为了完整起见,我现在使用的代码摘录 use std::num::Float; use std::ops::Add; #[derive(Debug, PartialEq, Eq, Copy)] pub
use std::num::Float;
use std::ops::Add;
#[derive(Debug, PartialEq, Eq, Copy)]
pub struct Vector<T: Float> {
x: T,
y: T,
z: T,
}
impl<T: Float> Add for Vector<T> {
type Output = Vector<T>;
// Probably it will be optimized to not actually copy self and rhs for each call !
#[inline(always)]
fn add(self, rhs: Vector<T>) -> Vector<T> {
Vector { x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z }
}
}
#[cfg(test)]
#[test]
fn basics() {
let v32 = Vector { x: 5.0f32, y: 4.0f32, z: 0.0f32 };
let v32_2 = v32 + v32;
assert_eq!(v32_2.x, v32.x + v32.x);
assert_eq!(v32_2.y, v32.y + v32.y);
assert_eq!(v32_2.z, v32.z + v32.z);
}
由于向量只包含三个实现Float-trait的值,这意味着它们要么是f64要么是f32,所以不必担心它们被复制,除非您已经分析了程序并确定多个副本会导致性能下降
例如,如果您的类型不可复制,并且在构造时需要分配大整数和大浮点数,则可以实现所有可能的按值和按引用调用组合:
impl Add<YourType> for YourType { ... }
impl<'r> Add<YourType> for &'r YourType { ... }
impl<'a> Add<&'a YourType> for YourType { ... }
impl<'r, 'a> Add<&'a YourType> for &'r YourType { ... }
在我看来很整洁-编译器已经很好地内联了所有操作。我个人认为,当使用“拥有”值时,编译器应该能够做得更好,因为它可以随意移动它们。我通常担心会产生不必要的副本,但在这方面,锈蚀可能会有所不同。正如我所想,锈蚀类型包括它们的“修改器”,如mut或&。Add被定义为pub-trait-Add,所以我假设Self的类型在所有方面都必须与RHS的类型相同。也许这也和生命有关。SomeType只定义了一个默认的类型参数,也就是说,如果没有指定它,则假定它是这样的。这允许书写,例如T:Add,翻译成T:Add。谢谢!我现在有很多尤里卡时刻,我试图学习锈迹的来龙去脉!就在几分钟前,我见过这样的代码,并正确地假设它是默认类型。就我而言,由于某些原因,我感到困惑。今天就到此为止,因为情况不再好转;这一答案在本文件中引用。
shrq $11, %r14
cvtsi2sdq %r14, %xmm0
mulsd .LCPI0_0(%rip), %xmm0
shrq $11, %r15
cvtsi2sdq %r15, %xmm1
mulsd .LCPI0_0(%rip), %xmm1
shrq $11, %rbx
cvtsi2sdq %rbx, %xmm2
mulsd .LCPI0_0(%rip), %xmm2
movaps %xmm0, %xmm3
addsd %xmm1, %xmm3
movaps %xmm1, %xmm4
addsd %xmm2, %xmm4
movaps %xmm0, %xmm5
addsd %xmm2, %xmm5
addsd %xmm2, %xmm3
addsd %xmm0, %xmm4
addsd %xmm1, %xmm5
movsd %xmm3, 24(%rsp)
movsd %xmm4, 32(%rsp)
movsd %xmm5, 40(%rsp)
leaq (%rsp), %rdi
leaq 24(%rsp), %rsi
callq _ZN13Vec3$LT$T$GT$9to_string20h7039822990634233867E