|
前一陣子分析了一個將近1TB的數(shù)據(jù)群(gz文件,壓縮率10%)。因為第一次分析如此巨大的數(shù)據(jù),沒有經(jīng)驗,所以浪費了許多時間。下面是我整理的一些經(jīng)驗,方便后者。
下載數(shù)據(jù)
Q:怎么自動下載多個文件?
這是我遇到的第一個問題。當數(shù)據(jù)量很大時,一般都會分成很多個文件存放。這時下載文件比較麻煩。
A:用Wget命令。Windows下花費一點時間去下載安裝。但之于手動下載,能省不少時間。
我提供兩種方式方式下載文件,
a)用Wget的遞歸下載選項 “-r”。一般命令如下
wget –r http://<下載數(shù)據(jù)的根目錄>/ -o <下載記錄文件名> -np
因為遞歸下載沒法控制進度,所以建議不一要次遞歸下載太多的文件
b)用Bat+Wget,多次執(zhí)行Wget。一般命令如下
wget –r http://<下載數(shù)據(jù)的根目錄分支1>/ -o <下載記錄文件名> -np
wget –r http://<下載數(shù)據(jù)的根目錄分支2>/ -o <下載記錄文件名> -np
wget –r http://<下載數(shù)據(jù)的根目錄分支3>/ -o <下載記錄文件名> -np
…… ……
wget –r http://<下載數(shù)據(jù)的根目錄分支N>/ -o <下載記錄文件名> -np
用Bat可以降低出錯帶來的影響。
另外,Wget可以通過 –A 選項來指定希望下載的文件的后輟,通過 –P 選項來指定下載文件存放路徑。更多命令,參見wget -h
Q:這速度。。。什么時候才能下完?網(wǎng)速永遠是個瓶頸
A:如果下載服務(wù)很遠的話,你應(yīng)該考慮代理。wget設(shè)置代理的方式如下
set http_proxy=http://<代理服務(wù)器>
不要忘了多開幾個進程,20個試試?
打開文件
Q:怎么打開文本文件
這不是弱智問題。你用記事本打開一個1000MB的文件試試
Large Text File viewer, 打開速度會讓你驚奇
Q:怎么打開二進制文件
你可以通過下面方式來選擇進制:
右擊數(shù)據(jù)區(qū) => Display As => Hex|Decimal|Octal|Binary|Float|Double
你可以通過下面方式來選擇按多少字節(jié)顯示:
右擊數(shù)據(jù)區(qū) => Group By => Bytes|Words|Double|Quad
編程語言
當數(shù)據(jù)量很大時,選擇語言要慎重了。因為不同語言有不同的特點,你要在編程時間和運行時間之間權(quán)衡。
模型測試
開始時,一般挑幾個小的數(shù)據(jù)進行測試,獲取第一份分析結(jié)果。這時當然希望能快速編程實現(xiàn)。腳本語言是一個很好的選擇,比如Python。
大量處理
開始遍歷處理所有數(shù)據(jù)時,用腳本語言來處理就不太合適了。因為腳本語言的運行時間不能讓人接受。另外,還有內(nèi)存使用,文件讀寫這些你都沒法控制。不幸的是,很少語言會為你處理海量文件做優(yōu)化。
這時,C/C++是最好的選擇。
結(jié)果展示
漫長的等待終于過去了,眼看就要出結(jié)果了。如果你還執(zhí)著于陪伴你度過漫長等待的C/C++的話,你遲早會沮喪的。
我嘗試了很多方式之后,得出的結(jié)論是,讓Matlab來接手C/C++。Matlab能輕而易舉地展示大量數(shù)據(jù)。更重要的是Matlab支持讀取二進制文件。
filename = 'out.bin'; % binary file
fid = fopen( filename );
data = fread( fid, itemsNumber, '*uint32');
fclose(fid);
算法
一次性讀文件
我已經(jīng)測試過好幾次了,一次性讀取文件比一行一行讀文件至少快五倍
記住O(N)
這時你要好好考慮算法的復(fù)雜度了。任何O(N2)的算法都不可取。
必要的時候可以通過空間來換時間。通常哈希表能節(jié)省不少時間。
并行處理
溫習(xí)一下并行算法。這比等待單線程程序好很多。
可以考慮在GPU上跑程序。當然,內(nèi)存和文件讀取時間更可能是瓶頸。
內(nèi)存、CPU、磁盤讀取速度,誰是瓶頸,任務(wù)管理器知道。
優(yōu)化核心代碼
通常80%的時間在運行20%的代碼。所以有空的話優(yōu)化下經(jīng)常經(jīng)常執(zhí)行的代碼。
分布式保存
把分析結(jié)果存在一個文件中是一個很糟糕的決定。這會為后面處理帶來很多麻煩。比如并行處理,文件過大等。
二進制方式保存中間數(shù)據(jù)
二進制方式存放通常能省一半的磁盤空間。這同時意味著減少一半的寫硬盤時間和讀硬盤時間。當然,還有文本轉(zhuǎn)換時間。
還有個重要細節(jié)要注意:在Windows中,讀寫文件的方式要改成”rb”和”wb”。要不然莫名的Bug遲早要發(fā)生,但不一定能找到。
運行
Debug Vs Release
別忘了,最終運行時把編譯方式換成Release。但是剛改完程序的話,建議先用Debug模式試跑一下。這樣能定位運行時異常。
批處理
批處理是降低運行出錯風(fēng)險的很好的方式。因為你不確定程序能正常結(jié)束。所以一段一段執(zhí)行程序是一個很好的選擇。如果某個地方出問題的話就不用重新運行前面的程序了。
斷言
當數(shù)據(jù)量很大時,很難保證輸入是合法的。另一種情況是,數(shù)據(jù)是合法的,但我們欠考慮了。這時斷言就顯得很重要了。斷言回增加運行時間,但總比花大量時間得到一個錯誤結(jié)果好。
記錄運行結(jié)果到文件
前面提到,數(shù)據(jù)量很大時,很難保證程序正常結(jié)束。一般,很少人會在顯示器旁坐等輸出結(jié)果。把運行情況定時記錄到文件是非常必要的。
另外,不要忘了fclose();
附:64位編程問題
數(shù)據(jù)量很大時,內(nèi)存通常是不夠用的。有一個常識必須知道:32位程序的最大尋址空間是2GB。如果你要分配接近或者超過2G內(nèi)存的話,試試64位程序吧。當然有兩條件:64位的CPU,64位的操作系統(tǒng)。
下面是編寫64位程序的一些經(jīng)驗
編譯環(huán)境
如果是解釋型語言,比如Python,則需要下載一個64位的Python解釋器
如果是編譯型語言,比如C/C++,則需要選擇恰當?shù)木幾g平臺。
比如VS2008中,項目屬性 => Configuration Manager => Platform => New => X64
分配大數(shù)組,應(yīng)該用malloc,而不是直接定義數(shù)組。
sizeof( int ) != sizeof( size_t )
64位程序中,數(shù)組下標應(yīng)該換成size_t,常數(shù)也需要強制轉(zhuǎn)換,比如 4GB = 4*(size_t)1000000000000文件
fwrite一次性寫入一個大于4GB的數(shù)組似乎有些問題。
分多次寫入文件試試。
it知識庫:如何分析海量數(shù)據(jù),轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。