Может ли компилятор сделать встраивание по умолчанию в метод признака? - PullRequest
0 голосов
/ 03 сентября 2018

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

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

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

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

1 Ответ

0 голосов
/ 03 сентября 2018

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

  • Будут ли встроенные вызовы компилятора 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
...