看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《danielpowter (daniel)》之銘言: : 我用STL 希望創造一個三維的VECTOR : 以下是我的宣告 : CUSTOMER=10000 : ITEMTYPE=10000 : BITARRAY=32 : vector<vector<vector<int> > > CBASW (CUSTOMER, vector<vector<int> >(ITEMTYPE, vector<int>(ARRAYBITS))); 這問題使我想起了之前的 GA-KMeans... 小弟試算一下.. 10000 * 10000 * 32 * 4 bytes (for int) = 32 * 4 * 100 MB = 12800 MB = 12.8 GB 即使是放 bool(這使我想到GA會用, 還有 KMeans-Clustering Mapping 會用) 也會花 3.2G, 這個大小對目前作業系統而已,還是沒辦法全都塞到記憶體裡。 不知道算出來這個數字對不對.. 分享遇過所需大記憶體的問題 當時手邊電腦配備很弱,只有 512MB 記憶體, 一開始以為把虛擬記憶體調大就沒這方面問題 後來發現還是沒辦法,於是先把所有東西都寫到檔案裡面去, 運用分段讀取的方式去讀寫,這麼做無疑執行速度整個變慢, 於是要花時間去優化寫入的速度。提供一下我之前優化寫入的做法 #define FIELD_LEN 20 unsigned write_len = 1800; // buffer 存到這麼長的時候再寫入 unsigned len=0; char read_buffer[2000]; char write_buffer[2000]; do{ CalValue(read_buffer); len = sprintf(write_buffer, "%*s",FIELD_LEN,read_buffer); }while(len<1800); fputs(fp, buffer); 一般小程式不會這麼做,不過 IO 一大,減少寫入的次數似乎是重要的事。 這裡要注意的是,裡面有用到 %20s 這種東西,代表固定長度是 20, 壞處是可能浪費空間,好處是位置都對齊了,到時候如果要讀檔, 用 fseek 就很快,這個你自己考量要怎麼寫入。 接著再根據檔案裡的內容做運算。檔名命名沒有一定規則, 以實際的情況做調整為佳。 ---------------------------------------------------------------- 簡易範例, 現假設三維的問題是: 有 X 個學生,每個學生有 Y 個工作項目, 每個工作項目有 Z 種解決方案, 每個解決方案所花成本不一, 要找出這 Y 個工作項目交由哪個學生做最適合, 如第一個工作項目 (y1) 交由第3個學生 (x3) 使用第4種方案 (z4) , 其成本最小,最小成本為 cost[x3][y1][z4] = 15 #define X 10000 #define Y 10000 #define Z 32 int cost[X][Y][Z]; 至於這些資料來源當作是從資料庫裡面讀出來的, (因為我不會讀資料庫,所以全轉成 .csv, .txt) step 1. 建立範本檔案 從原始資料庫裡先進行建檔動作,這部份會花較久時間, 但可用上述的小技巧加快寫入動作。 把所有工作項目(Y) 對應到的學生(X)-方案(Z)建立一個檔案, y1.txt 內容 - [y1][x1][z1], [y1][x2][z2], .... [y1][xX][zZ] 這樣下來一個檔案大小為 X*Z*4 = 10000*32*4 = 1280000 = 1.28MB, 共有 Y(10000) 個檔案 step 2. 建立之範本檔案仍為過大時 這時就再細分檔案,變成 y1x1.txt 內容 - [y1][x1][z1] [y1][x1][z2] [y1][x1][z3] .... [y1][x1][zZ] 這樣一個檔案大小為 Z*4 = 40000 = 4KB 共有 X*Y = 10000*32 = 320000 個檔案 不過用到這麼多檔案,到時開檔時的速度會變更慢。 step 3. 讀出比較 接著就沒什麼好說的,就一個一個開檔,取出來的變數存下來而已, 如果是用 step 2 方式建檔的話,那會變得比較麻煩, 不過該拿出來的還是拿得出來 -------------------------------------------------------- 以上是我之前的經驗,這不是一個很有效率的方式, 只是當時在趕時間,所以程式也快些寫沒再想太多, (就真的只有求有而已) 至於其它更好的方法,倒是期待各位版友的不吝分享與指教。 以上,謝謝收聽。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.142
loveme00835::) 01/06 22:51
nowar100:push 01/06 23:43
xatier:推 01/07 07:31
tomap41017:感謝經驗分享,很受用!! 01/07 22:05
ericinttu:我想問一下, 像這類超大資料的程式, 是否能借用DBMS 那 01/08 18:54
ericinttu:些有能力處理超多筆紀錄的系統來做為開發環境? 01/08 18:56
tropical72:我沒實際處理真正的資料庫過,所沒不是那麼清楚,當時會 01/09 15:28
tropical72:想要再轉成csv處理純粹是到時做二次處理時讀寫檔速度 01/09 15:29
tropical72:也較快,不然資料庫一大,我想大多時間也是花在讀檔上吧 01/09 15:29