我有大約1.5 Gb的浮點數以ASCII空格分隔的數據文件,例如1.2334 2.3456 3.4567
等等。讀取大量的ASCII數字並以二進制格式寫入
在處理這些數字之前,我首先將原始文件轉換爲二進制格式。這很有幫助,因爲我可以選擇是使用float
還是double
,減小文件大小(對於double
約爲800 MB,對於float
約爲400 MB),並在處理數據後以適當大小讀取塊。
我寫了下面的功能,使ASCII到二進制翻譯:
template<typename RealType=float>
void ascii_to_binary(const std::string& fsrc, const std::string& fdst){
RealType value;
std::fstream src(fsrc.c_str(), std::fstream::in | std::fstream::binary);
std::fstream dst(fdst.c_str(), std::fstream::out | std::fstream::binary);
while(src >> value){
dst.write((char*)&value, sizeof(RealType));
}
// RAII closes both files
}
我想來加速acii_to_binary
,我似乎無法拿出任何東西。我嘗試以8192字節的塊讀取文件,然後嘗試在另一個子例程中處理緩衝區。這看起來非常複雜,因爲緩衝區中的最後幾個字符可能是空白(在這種情況下一切都很好),或者截斷的數字(這非常糟糕) - 處理可能的截斷的邏輯似乎不值得。
你會怎麼做才能加快這個功能?我寧願依賴於標準的C++(C++ 11是OK),而不需要額外的依賴,比如boost。
謝謝。
編輯:
@DavidSchwarts:
我試圖實現您的建議如下:
template<typename RealType=float>
void ascii_to_binary(const std::string& fsrc, const std::string& fdst{
std::vector<RealType> buffer;
typedef typename std::vector<RealType>::iterator VectorIterator;
buffer.reserve(65536);
std::fstream src(fsrc, std::fstream::in | std::fstream::binary);
std::fstream dst(fdst, std::fstream::out | std::fstream::binary);
while(true){
size_t k = 0;
while(k<65536 && src >> buffer[k]) k++;
dst.write((char*)&buffer[0], buffer.size());
if(k<65536){
break;
}
}
}
但它似乎並沒有被寫入數據!我的工作就可以了...
你的意思是說文件大小減小到800 * M * B不是800 * G * B? –
我想你會發現使用經典的C'FILE *'和'fscanf()'會比使用'fstream'快一點點。 [也不要認爲你應該在你的輸入文件中使用'fstream :: binary' - 它可能對性能沒有任何影響,但是正確性會受到影響。 –
@丹弗 - 是的。謝謝! – Escualo