2013-04-25 73 views
3

我正在開發一個實時應用程序,有時我需要用相同的數據創建實例到新的對象。copy.deepcopy還是新建一個對象?

首先,我只是實例化它們,但後來我意識到可能用copy.deepcopy它會更快。現在,我發現有人說deepcopy速度非常慢。

我不能做簡單的copy.copy,因爲我的對象有列表。

我的問題是,你知道更快的方式,或者我只需要放棄並再次實例化它們? 謝謝你的時間

+1

我想知道,如果我只是在這些對象中添加一個'def __copy __(self):'並且只是將這些對象內部的這些列表複製回來呢? – XNor 2013-04-25 10:01:34

+0

'deepcopy'只是遞歸遍歷結構並創建新的實例。避免無限循環並且可以定製是很明智的,就是這樣。 – 2013-04-25 10:10:09

+0

因此'deepcopy'會檢查你所有的列表值,看看它們是否也需要複製;創建列表的新副本的'__copy__'將有助於避免這種情況,是的。 – 2013-04-25 10:11:09

回答

3

我認爲copy.deepcopy()仍然是純Python,所以它不可能給你任何速度提升。

這聽起來有點像早期優化的經典案例。我建議編寫你的代碼是直觀的,在我看來,它只是簡單地實例化每個對象。然後,您可以對其進行概況分析,並查看需要在哪裏進行節省的地方。很可能在您的實際使用情況中,一些完全不同的代碼將成爲瓶頸。

編輯:有一件事我忘了我原來的答覆說 - 如果你複製一個列表,請確保您使用切片表示法(new_list = old_list[:]),而不是通過迭代它在Python,它會慢一些。但是,這不會進行深層複製,因此如果您的列表中有其他列表或字典,則需要使用deepcopy()。對於dict對象,請使用copy()方法。

如果你仍然發現構建你的對象是需要花費時間的,那麼你可以考慮如何加速它。你可以嘗試__slots__,雖然他們通常關於節省內存超過CPU時間,所以我懷疑他們會買你很多。在極端情況下,您可以將對象推送到C擴展模塊,這可能會以增加複雜性爲代價而快得多。這一直是我過去採用的方法,我在其中使用本地C數據結構,並使用Python的特殊方法在頂部包裝「類列表」或「字典」界面。當然,這確實取決於你對C編碼感到滿意。

(順便說一句我會避免C++,除非你有一個令人信服的理由,C++ Python擴展是稍微繁瑣獲得建築比普通的C - 這是完全可能的,如果你有一個良好的動機,不過)

如果例如,你的對象有很長的列表,那麼你可能會從某種寫時複製方法中獲得一些里程,在這種方法中,對象克隆只保留相同的引用而不是複製列表。每次訪問它們時,您都可以使用sys.getrefcount()來查看就地更新是否安全或是否需要複製。這種方法很可能很容易出錯並且過於複雜,但我想我會提及它的興趣。

您還可以查看您的對象層次結構並查看是否可以將對象分解爲不需要重複的部分可以在其他對象之間共享。同樣,在修改這些共享對象時,你需要小心。

重要的一點,然而,就是你第一希望得到您的代碼正確然後使你的代碼快速一旦你瞭解做的最好的方式,從現實世界中的使用。

+0

謝謝你,那很聰明。 – XNor 2013-04-25 10:22:17

相關問題