2012-04-22 18 views
5
%python -m timeit -s "import copy" "x = (1, 2, 3)" "copy.deepcopy(x)" 
100000 loops, best of 3: 10.1 usec per loop 

%python -m timeit -s "import copy" "x = (1, 2, 3)" "copy.copy(x)" 
1000000 loops, best of 3: 0.609 usec per loop 

पर copy.deepcopy प्रदर्शन क्यों deepcopy 15 बार copy की तुलना में धीमी है?copy.copy बनाम tuples

प्रत्येक कार्य को ट्यूपल के तत्वों के माध्यम से पुन: सक्रिय करना होता है। उस पुनरावृत्ति के दौरान, copy प्रत्येक तत्व के लिए एक और संदर्भ बनाता है; deepcopy प्रत्येक तत्व को गहराई से।

लेकिन प्रत्येक तत्व int है, और int को गहराई से बस इसके लिए एक और संदर्भ बनाता है। दूसरे शब्दों में, दो कार्य ठीक उसी चरण, समान संख्या में प्रदर्शन करने लगते हैं।

यहाँ सत्यापन कि कोई नया उदाहरणों प्रक्रिया में बनाए जाते हैं है:

ActivePython 3.2.1.2 (ActiveState Software Inc.) based on 
Python 3.2.1 (default, Jul 18 2011, 14:31:09) [MSC v.1500 64 bit (AMD64)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> x = (1,2,3) 
>>> import copy 
>>> y = copy.copy(x) 
>>> z = copy.deepcopy(x) 
>>> x is y 
True 
>>> x is z 
True 
>>> x[1] is z[1] 
True 
+1

नहीं एक असली जवाब है, लेकिन एक संदेह: 'deepcopy' ट्रैक जो तत्व यह पहले से ही चक्रीय संदर्भ, कुछ भूमि के ऊपर जोड़ सकते हैं, जो विशेष रूप से इस तरह के साधारण मामलों में के लिए अनुमति देने के लिए नकल की है रखने की जरूरत है। – Philipp

+0

यदि आप अपनी "गहरी प्रतिलिपि" की प्रतिलिपि बना सकते हैं तो यह इसके लायक हो सकता है। मैं कुछ विकासवादी एल्गोरिदम कोड का प्रोफाइल कर रहा था और यह गहरे रंग में बहुत समय बिता रहा था। मैं एल्गोरिदम के लिए आवश्यक बाधाओं को निर्धारित करने में सक्षम था और गहरे रंग के अपने सीमित संस्करण को लिखने में सक्षम था जो काफी गति-गति का कारण बनता है। आपकी माइलेज भिन्न हो सकती है। – Levon

उत्तर

6

tuples अपरिवर्तनीय हैं, लेकिन वे परिवर्तनशील तत्व हो सकते हैं:

>>> a = (1, 2, []) 
>>> a[2].append(1000) 
>>> a 
(1, 2, [1000]) 

ध्यान दें कि टपल परिवर्तन नहीं करता है : यह वह सूची है जो करता है; टुपल में अभी भी एक ही सूची है।

deepcopy उन उत्परिवर्तनीय तत्वों की प्रतिलिपि बनाना चाहिए। copy सिर्फ उन संदर्भों की प्रतिलिपि बनाता है।

>>> from copy import copy, deepcopy 

>>> a = (1, 2, []) 
>>> c = copy(a) 
>>> d = deepcopy(a) 

>>> a[2].append(1000) 

>>> c 
(1, 2, [1000]) 
>>> d 
(1, 2, []) 
+1

हां, लेकिन दोनों 'प्रतिलिपि' और 'गहरी प्रतिलिपि' को ट्यूपल के तत्वों के माध्यम से पुन: सक्रिय करने की आवश्यकता है। जैसा कि वे करते हैं, 'प्रतिलिपि' प्रत्येक 'int' के लिए एक और संदर्भ बनाता है, जबकि' deepcopy' 'int' उदाहरण की प्रतिलिपि बनाता है। लेकिन 'int' इंस्टेंस की प्रतिलिपि बनाना एक ही उदाहरण के लिए एक और संदर्भ देता है। ऐसा लगता है कि दोनों कार्यों को ठीक उसी कदम करना चाहिए। मैं नहीं देखता कि 15x प्रदर्शन में इसका परिणाम कैसा रहा। – max

+1

मुझे नहीं लगता कि उथले प्रतिलिपि के लिए ट्यूपल पर फिर से जरूरी है। पाइथन आंतरिक के बारे में इतना जानने के बिना, मुझे लगता है कि एक memcpy कॉल पर्याप्त होना चाहिए। –

+3

आप सही हैं, 'प्रतिलिपि' के लिए पुन: प्रयास करने की कोई आवश्यकता नहीं है। पायथन को 'memcpy' की भी आवश्यकता नहीं है: यह सिर्फ मूल tuple के लिए एक और संदर्भ वापस कर सकते हैं! बेशक, वह 'गहरी चोटी' के लिए काम नहीं करेगा। – max