Copy_from_slice () के बजाय clone_from_slice () का उपयोग करने का प्रदर्शन दंड?

Aug 15 2020

जंग में, एक स्लाइस की सामग्री को दूसरे स्लाइस से अपडेट करने के दो तरीके हैं: clone_from_slice()और copy_from_slice()। इन दो कार्यों का व्यवहार अनिश्चित है - पहला एक क्लोन करता है और प्रकार को लागू करने की अपेक्षा करता है Clone, जबकि दूसरा एक कॉपी करता है और कार्यान्वयन के प्रकार की अपेक्षा करता है Copy

हालांकि, यह मुझे आश्चर्यचकित करता है कि इसके लिए प्रलेखन clone_from_sliceयह कहता है: "यदि Tलागू होता है Copy, तो इसका उपयोग करने के लिए अधिक प्रदर्शन हो सकता है copy_from_slice।" यह आश्चर्य की बात है कि यहां एक प्रदर्शन अंतर होना चाहिए। यदि Tलागू होता है Copy, तो .clone()प्रतिलिपि बिट्स के बराबर होना आवश्यक है; हालाँकि जब से संकलक को पता है कि क्या प्रकार Tहै, तो यह पता लगाने में सक्षम होना चाहिए कि अगर मैं उपयोग करता हूं तो यह एक बिटवाइज़ कॉपी भी कर सकता है clone_from_slice

तो प्रदर्शन अक्षमता कहाँ से उत्पन्न होती है?

जवाब

4 ÖmerErden Aug 15 2020 at 21:14

TL; DR कृपया clone_from_slice के स्रोत की जांच करें , यह स्लाइस के सभी तत्वों का दौरा कर रहा है और cloneप्रत्येक के लिए कॉल कर रहा है, जबकि copy_from_slice सीधे सभी बिट्स की प्रतिलिपि बनाता है memcpy


यदि टी लागू होता है Copy, तो .clone()प्रतिलिपि बिट्स के बराबर होना आवश्यक है

भले ही हर Copyप्रकार Cloneडिफ़ॉल्ट रूप से लागू होगा जहां cloneसीधे उपयोग करेंcopy ; clone_from_sliceअभी भी स्लाइस का पता लगाएगा और ट्रैवर्सिंग करते हुए कॉपी करेगा।

लेकिन यह प्रस्ताव आदिम के लिए सही नहीं है, लेकिन नीचे दिए गए मामलों के लिए सही नहीं है :

#[derive(Copy)]
struct X;

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

        X
    }
}

जबकि Cloneकिसी भी तर्क Copyप्रकार द्वारा कार्यान्वित किया जा सकता है बस एक वस्तु की नकल करते समय बिट की नकल करेंगे।

यदि टी लागू होता है Copy, तो इसका उपयोग करने के लिए अधिक प्रदर्शन हो सकता हैcopy_from_slice

महत्वपूर्ण बात यहां है, प्रलेखन कहता है " यह " हो सकता है " यह नहीं होगा ", यह जैसी संभावनाएं लाता है

  • Cloneकार्यान्वयन सीधे Copyकार्यान्वयन का उपयोग कर सकता है । आदिम जैसे बुनियादी प्रकारों के लिए, memcpyअनुरेखक ट्रैवर्सिंग के बजाय सीधे उपयोग कर सकते हैं , तो हम इस प्रस्ताव को गलत मान सकते हैं क्योंकि एक प्रदर्शन नहीं करेगा, फिर अन्य।

  • Cloneकार्यान्वयन सीधे Copyकार्यान्वयन का उपयोग कर सकता है । जटिल प्रकारों (ऊपर दी गई समस्या के लिए) इस प्रस्ताव को सही बनाता है। (मैंने @kmdreko से उदाहरण को थोड़ा और अधिक जटिल संरचना के साथ संपादित किया है , कृपया गॉडबोल्ट से परिणाम देखें )

  • Cloneकार्यान्वयन कस्टम है और यह एक Copyप्रकार है, यह एक इस प्रस्ताव को सही बना देगा यहां तक ​​कि कस्टम कार्यान्वयन भी सस्ता है तो copyबड़े स्लाइस के लिए उपयोग memcpyकरना अधिक फायदेमंद हो सकता है।