2008-12-16 59 views
2

我有一大組數據(一個250,000 X 1000雙倍的數據立方體,大約4個gig文件),我想用前面用Python編寫的一組OOP類來操縱它。目前數據集已經非常大,以至於讀入我的機器內存,我不得不至少將它分成兩半,所以計算開銷是一個問題。我的OOP類創建新對象(在這種情況下,我將需要250,000個新對象,每個對象是一個包含1,000個雙打的數組)來處理數據。在爲通用OOP語言創建對象所需的內存和計算方面的開銷是多少?在python中?在C++中怎麼樣?什麼是面向對象的編程計算開銷成本?

是的,我意識到我可以創建一個新的類是一個數組。但是1)我已經完成了這些類,並且2)我將創建的每個對象都放回到數組中供以後訪問。問題是教育

*更新:我想與時間,我的時間和電腦高效。我不想重寫我已經擁有的程序,如果我不必花時間優化代碼浪費時間,我不在乎太多了,如果我浪費電腦時間。我實際上有一個4Gig ram的64位機器。該數據是一個圖像,我需要對每個像素做幾個過濾器。*

+0

通常使用簡單的數據結構和針對大數據集優化的特定算法計算大數據。你在這裏似乎並沒有走上正確的道路。你想實現什麼? – Loki 2008-12-16 20:44:57

回答

2

http://code.activestate.com/recipes/546530/

這是Python對象的近似大小。

OO大小的「懲罰」常常被(a)簡化處理和(b)在內存中保留較少內容的能力所抵消。

沒有OO性能開銷。零。在C++中,類定義已經過優化,所有你剩下的就是C.在Python中 - 和所有動態語言一樣 - 動態編程環境增加了一些運行時查找。大多數情況下,這些都是直接散列成字典。它比編譯器爲您解決所有問題的代碼慢。然而,它仍然非常快,開銷相對較低。

C中的錯誤算法可能比Python中的正確算法慢。

0

如果不知道數據的形狀以及您設計用來包含它的結構,將無法回答。

+0

你能在這裏解釋更多嗎? – Alex 2008-12-16 20:12:54

+0

你的問題是他的問題:) – 2008-12-16 20:27:09

2

我不認爲把你的設計的任何缺點歸咎於OOP是不公平的。就像任何其他編程平臺一樣,面向對象可以用於優化設計和優化設計。這很少會成爲編程模型本身的錯。

但試圖回答你的問題:分配250000個新對象需要我知道的所有OO語言的一些開銷,所以如果你能通過同一個實例流式傳輸數據,那麼你可能會更好關閉。

3

你會遇到與過程/函數式編程語言類似的問題。你如何將大量數據存儲在內存中?結構或數組也不會工作。

您需要採取特殊步驟來管理這種數據規模。

順便說一句:我不會用這個作爲選擇OO語言的理由。

0

「開銷」在很大程度上取決於您選擇的平臺和實現。

現在,如果您有一個內存問題從多個Gb文件中讀取數百萬的數據,您會遇到一個算法問題,其中對象的內存消耗絕對不是最大的問題,您關心的問題更多獲取,處理和存儲數據。

0

像其他海報一樣。我不相信對象會爲您的流程帶來大量的開銷。它需要存儲一個指向對象的指針,但其餘的'雙打'將佔用程序內存的99%。

你可以將這些數據分成更小的子集嗎?你試圖完成什麼任務?我會感興趣的是看到你需要什麼內存中的所有數據。也許你可以序列化它,或者使用像haskell中的懶惰評估之類的東西。

請發表後續內容,以便我們更好地瞭解您的問題域。

0

我不認爲這個問題是來自面向對象的開銷。

如果我們接受C++作爲面向對象的語言,並記住C++編譯器是C的預處理器(至少它曾經是,當我使用C++時),在C++中完成的任何事情都是在C中完成的。很少的開銷。所以這取決於圖書館。

我認爲任何開銷都會來自解釋,管理執行或內存管理。對於那些有工具和專有技術的人來說,找出最有效的C++或Python是非常容易的。

我看不到C++會在哪裏添加很多可避免的開銷。我不太瞭解Python。

0

相比,你的數據集的大小,250K對象的開銷可以忽略不計

我認爲你是在錯誤的道路上;不要責怪對象;-)

0

請定義「操縱」。如果你真的想要操作4個數據集,爲什麼你想通過把它全部存入內存來操縱它?

我的意思是,誰需要4演出RAM呢? :)

3

稍微OT:flyweight design pattern可用於最小化操作大型數據集時的開銷。不知道你的問題的細節,我不知道它是如何適用它,但它值得一看...

1

實際的C + + OO內存開銷是一個指針(4-8字節,具體取決於)每個對象與虛擬方法。但是,正如其他答案中所提到的那樣,動態分配的默認內存分配開銷可能會遠遠大於此。

如果您在中途合理地進行操作,與1000 * 8字節的雙數組相比,開銷可能不會很大。如果你真的擔心分配的開銷,你可以編寫你自己的分配器 - 但是,首先檢查它是否真的會給你帶來顯着的改進。

0

如果您必須定期處理這麼大的數據集,您是否可以獲得帶有桶加載的RAM的64-bit machine?出於各種原因,我發現自己正在使用相當耗資源的軟件(在這種情況下是SQL Server Analysis Services)。這類老式的64位機器可能會佔用大量的RAM,而功能性CPU雖然不是最前沿,但速度仍然相當快。

我得到了一些二手惠普工作站,併爲他們安裝了幾個快速SCSI磁盤。在2007年年中,這些具有4或8GB RAM和5x 10K或15K SCSI磁盤的機器的價格在1500到2000英鎊之間。磁盤是機器成本的一半,您可能不需要I/O性能,因此您可能不需要花費太多。我買的那種XW9300's現在可以相當便宜地購買ebay - this posting of mine進入各種選擇使用易趣得到一個高規格的64位盒便宜。您可以從ebay獲得這些機器的內存升級至16或32GB,這些部件的價格相當小。

0

我的一位朋友是麻省理工學院的教授,一位學生問他爲什麼他的圖像分析程序運行得如此緩慢。它是如何建造的?每個像素都是一個對象,並且會向鄰居發送消息!

如果我是你,我會在一次拋棄式的程序中嘗試它。我的懷疑是,除非你的類是非常仔細的編碼,否則你會發現它花費了大量的時間分配,初始化和取消分配對象,正如Brian所說,你可能能夠通過一組的重用對象。編輯:對不起。你說你正在重新使用對象,所以這很好。無論如何,當你開始運行時,你可以對它進行簡要描述,或者(如果你是我)只需幾次隨機讀取調用堆棧,這將回答關於時間在哪裏的任何問題。

0

由於您可以將數據分成一半並對其進行操作,我假設您正在單獨處理每條記錄?在我看來,你需要改變你的反序列化器一次讀取一條記錄,操縱它,然後存儲結果。

基本上你需要一個字符串解析器類,它執行一個Peek(),它返回一個字符,知道如何跳過空格等。將一個類理解爲你的數據格式,並且你應該能夠吐出它在讀取文件時一次讀出一個對象。