這篇算是心得文,持有不同意見或補充歡迎提出。

不論是 shallow coyp 或 deep copy,筆者認為,並非所有情況都適用,且均會帶來不同之 side effect,但不論是哪種,設計前題均是,必須對記憶體之配置必須正確掌控。

shallow copy 只複制其 array 開頭 (該說是動態指標之 address 較為適宜),對同一份資料進行修改,故執行完時會影響原本之資料;而 deep copy 為本身再複制一份相同之 array 出來,所有運算和結果存在副本裡面,不影響原本之資料。

不論是 C、C++ 或其他程式語言,額外之 library 也有不同之選擇,筆者較建議以普遍性使用記憶體狀況為主,若問題一大、使用記憶體量大時,較適合用 shallow copy,因若進行 deep copy,可能使得記憶體不夠用。若所需記憶體使用量都算小時,較建議以易用為準則,使用 deep copy 。

以 class 設計而言,只要該 class 有用到動態記憶體配置,幾個部份幾乎是必定重改寫:operator = 、constructor 、destructor,甚至一些經驗法則 (誰的經驗 ? oh, 原諒筆者不知道是誰的經驗,只能說是 "普遍性" 大多數 coder 的經驗) 提出,凡舉 Matrix、BigNumber、String 之類別,大多之設計都以 deep copy 為主,一方面在 coding 過程中少了大多數容易造成 double delete 外,此份類別在使用上也較為直覺,或說是簡易、友善 (friendly)。

只有少數情況,筆者認為是必須 「考慮」使用 shallow copy :

(0) 對於速度有迫切的需求

由於 deep copy 會把陣列元素再逐一複制出來,故效率會稍慢一點。或許這會回到 "維護性"、"可讀性" 與 "效率" 之衡量問題,但對大多數專案而言, 維護性 與 可讀性 似乎較為開發團隊所重視之前提,而非效率面。若對效能上有迫切之需求,則可考慮使用 shall copy 方式,唯設計上將會比 deep copy 來得麻煩些。

(1) 處理對於較大記憶體之需求

對於一些需要大量記憶體之問題,且系統能提供之記憶體有限之情況下 (受限於作業系統與實際記憶體),使用 deep copy 並不妥當,此時反而以 shallow copy 較為適當。而此類型之 class、library 在設計時,較常以  Class::AllocateMemory、Class::Copy、Class::ReleaseMemory 方式設計,而不直接放在 Constructor、Destructor、operator = ,雖使用上稍較不便,但應較適合處理大量記憶體之問題。

edisonx 發表在 痞客邦 PIXNET 留言(1) 人氣()


留言列表 (1)

發表留言
  • novus
  • 這只是基礎概念,進階的實作常常會採用 copy-on-write 或是更複雜的 lazy evaluation。你可以參考這篇的 COW
    http://www.gotw.ca/gotw/043.htm

    shared_ptr 已經成為 C++ 標準,善加利用可以讓實作變得非常簡單。

    至於 lazy evaluation 能做的比 COW 還多很多,對於矩陣、向量、大數之類幾乎都是必備。事實上初學者寫的玩具級矩陣 class,要是真的拿來實用都會比 Fortran 慢很多,甚至和直譯的 matlab 比都還差得遠,其中一個關鍵就是初學者都不懂 lazy evaluation(當然原因不只這一個)。

    (之前我真的看到有人發問:我用的明明是最「貼近機器」的C/ASM,為什麼做XXX反而比 Fortran/matlab慢...)
  • 看完 novus 的意見,很多東西我想只能先去評估要自己寫,或去評估 library 效能如何了。

    edisonx 於 2011/12/29 02:52 回覆

您尚未登入,將以訪客身份留言。亦可以上方服務帳號登入留言

請輸入暱稱 ( 最多顯示 6 個中文字元 )

請輸入標題 ( 最多顯示 9 個中文字元 )

請輸入內容 ( 最多 140 個中文字元 )

請輸入左方認證碼:

看不懂,換張圖

請輸入驗證碼