Copy_from_slice () yerine clone_from_slice () kullanmanın performans cezası?

Aug 15 2020

Rust'ta, bir dilimin içeriğini başka bir dilimden güncellemenin iki yöntemi vardır: clone_from_slice()ve copy_from_slice(). Bu iki işlevin davranışı şaşırtıcı değildir - birincisi bir klon yapar ve türün uygulanmasını Clonebeklerken, ikincisi bir kopya yapar ve türün uygulanmasını bekler Copy.

Bununla birlikte, belgelerin şunu belirtmesi beni şaşırtıyor clone_from_slice: "Eğer Tuygularsa Copy, kullanımı daha performanslı olabilir copy_from_slice." Burada bir performans farkı olması şaşırtıcı. Eğer Tuygularsa Copy, .clone()bitleri kopyalamaya eşdeğer olması gerekir; ancak derleyici türünün ne olduğunu bildiğinden T, kullansam bile bitsel bir kopya yapıp yapamayacağını anlayabilmelidir clone_from_slice.

Peki, performans verimsizliği nereden kaynaklanıyor?

Yanıtlar

4 ÖmerErden Aug 15 2020 at 21:14

TL; DR Lütfen clone_from_slice'ın kaynağını kontrol edin, dilimin tüm öğelerini ziyaret ediyor ve cloneher biri için çağırıyor , copy_from_slice ise tüm bitleri doğrudan kopyalar memcpy.


T uygularsa Copy, .clone()bitleri kopyalamaya eşdeğer olması gerekir

Her Copytür, Clonevarsayılan cloneolarakcopy ; clone_from_sliceyine de dilimi çapraz geçecek ve çapraz geçiş sırasında kopyalama yapacak.

Fakat bu önerme ilkel ifadeler için doğru değil, aşağıdaki gibi durumlar için doğru değildir :

#[derive(Copy)]
struct X;

impl Clone for X {
    fn clone(&self) -> Self {
        //do some heavy operation or light(depends on the logic)

        X
    }
}

Bununla birlikte Clone, herhangi bir mantık Copytürü tarafından uygulanabilir, bir nesneyi çoğaltırken basitçe bitleri kopyalayacaktır.

T uygularsa Copy, kullanmak daha performanslı olabilircopy_from_slice

Önemli olan burada mı, dokümantasyon "diyor olabilir ki " değil " öyle olacak ", böyle olanaklarını getiriyor

  • Cloneuygulama, uygulamayı doğrudan kullanabilir Copy. İlkel türler gibi temel türler için, optimize edici memcpy, geçiş yapmak yerine doğrudan kullanabilir , bu durumda bu önermeyi yanlış kabul edebiliriz, çünkü biri diğerinden daha performanslı olmayacaktır.

  • Cloneuygulama, uygulamayı doğrudan kullanabilir Copy. Karmaşık türler için (yukarıdaki çaprazlama sorunu) bu önermeyi doğru yapar. ( @Kmdreko'daki örneği biraz daha karmaşık bir yapıyla düzenledim , lütfen godbolt'un sonucunu kontrol edin )

  • Cloneuygulama özeldir ve bir Copytürdür, bu, özel uygulama ucuz olsa bile bu önermeyi doğru yapar, o zaman copybüyük dilimler için kullanmak memcpydaha faydalı olabilir.