编译器可以对特征的方法进行默认实现的内联吗?



我知道特质的方法没有主体,所以没有什么可以内联的。但是像这样标记其默认实现有什么意义吗?

trait Magnitude {
fn square_magnitude( &self ) -> f64;
#[inline]
fn magnitude( &self ) -> f64 {
self.square_magnitude().sqrt()
}
}

在实现类型的 trait 时,我是否需要重写整个方法主体并用#[inline]标记这个 impl 的方法,而不是像上面那样只标记 trait 的方法?

如果我正确理解这个问题,你问的是两件事:

  • 编译器会内联调用magnitude吗?
  • 如果square_magnitude本身被声明为inline,即使square_magnitude的代码在 trait 中不可用,编译器是否能够内联对magnitude内部square_magnitude的调用?

至于第一个,没有理由不能。至于第二个答案是肯定的,编译器将能够内联这两个函数,因为当它生成代码时,两个函数的源代码都可用。这可以从反汇编中看出:

trait Magnitude {
fn square_magnitude( &self ) -> f64;
#[inline]
fn magnitude( &self ) -> f64 {
self.square_magnitude().sqrt()
}
}
struct Vector { x: f64, y: f64 }
impl Magnitude for Vector {
#[inline]
fn square_magnitude (&self) -> f64 {
self.x*self.x + self.y*self.y
}
}
pub fn test (x: f64, y: f64) -> f64 {
let v = Vector { x: x, y: y };
v.magnitude()
}

使用 rustc v1.28.0 和选项-O编译:

example::test:
mulsd   xmm0, xmm0
mulsd   xmm1, xmm1
addsd   xmm1, xmm0
xorps   xmm0, xmm0
sqrtsd  xmm0, xmm1
ret

但请注意,如果编译器本身未声明square_magnitudeinline则编译器不会magnitude内联square_magnitude

impl Magnitude for Vector {
fn square_magnitude (&self) -> f64 {
self.x*self.x + self.y*self.y
}
}

生成:

<example::Vector as example::Magnitude>::square_magnitude:
movsd   xmm1, qword ptr [rdi]
movsd   xmm0, qword ptr [rdi + 8]
mulsd   xmm1, xmm1
mulsd   xmm0, xmm0
addsd   xmm0, xmm1
ret
example::test:
mulsd   xmm0, xmm0
mulsd   xmm1, xmm1
addsd   xmm1, xmm0
xorps   xmm0, xmm0
sqrtsd  xmm0, xmm1
ret

相关内容

  • 没有找到相关文章

最新更新