Может ли компилятор сделать встраивание метода по умолчанию в метод черты?

Я понимаю, что метод черты не имеет тела, поэтому нечего встраивать. Но есть ли смысл помечать реализацию по умолчанию, как это?

trait Magnitude {
    fn square_magnitude( &self ) -> f64;

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

Нужно ли переписать все тело метода и пометить метод этого impl с #[inline] при реализации черты для типа, а не маркировать только метод черты, как указано выше?

1 ответ

Решение

Если я правильно понимаю вопрос, вы задаете две вещи:

  • Будут ли встроенные вызовы компилятора magnitude?
  • Сможет ли компилятор встроить вызов square_magnitude внутри magnitude если square_magnitude сам объявлен inline хотя код для 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_magnitude внутри magnitude если square_magnitude не объявлено inline сам:

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
Другие вопросы по тегам