[英]Optimizing IO in C++
我在優化C ++程序以實現最快的運行時遇到了麻煩。
該代碼的要求是輸出2個長整數之差的絕對值,並通過文件將其饋送到程序中。 即:
./myprogram < unkownfilenamefullofdata
文件名未知,每行有2個數字,以空格分隔。 有未知數量的測試數據。 我創建了2個測試數據文件。 一種是極端情況,長達5輪。 至於另一個,我使用一個Java程序生成2,000,000個隨機數,並將其輸出到一個timedrun文件中-相當於18.MB的測試。
大量文件的運行時間為3.4秒。 我需要將其分解為1.1秒。
這是我的代碼:
int main() {
long int a, b;
while (scanf("%li %li",&a,&b)>-1){
if(b>=a)
printf("%li/n",(b-a));
else
printf("%li/n",(a-b));
} //endwhile
return 0;
}//end main
我在程序上運行了Valgrind,它表明在讀取和寫入部分中有很多阻礙。 如果我知道我只會收到一個數字,該如何將打印/掃描重寫為最原始的C ++形式? 有沒有一種方法可以將數字掃描為二進制數字,並通過邏輯運算處理數據以計算出差異? 我還被告知要考慮編寫一個緩沖區,但是經過大約6個小時的網上搜索並嘗試編寫代碼,我沒有成功。
任何幫助將不勝感激。
您需要做的是將整個字符串加載到內存中,然后從那里提取數字,而不是重復進行I / O調用。 但是,您可能會發現,從硬盤驅動器加載18MB只是花費大量時間。
正如您所建議的,問題在於讀取所有這些數字並將其從文本轉換為二進制。
最好的改進是從任何將二進制數生成的程序中寫出數字。 這將大大減少必須從磁盤讀取的數據量,並略微減少從文本轉換為二進制文件所需的時間。
您說2,000,000個數字占用18MB =每個數字9個字節。 這包括空格和行標記的結尾,因此聽起來很合理。
將數字存儲為4字節整數將減少必須從磁盤讀取的數據量的一半。 在節省格式轉換的同時,可以預期性能會提高一倍。
由於您需要更多,因此需要更根本的東西。 您應該考慮將數據文件拆分為單獨的文件,每個文件都放在自己的磁盤上,然后在自己的進程中處理每個文件。 如果您有4個核心並將處理分成4個獨立的進程,並且可以連接4個高性能磁盤,那么您可能希望性能再提高一倍。 現在的瓶頸是操作系統磁盤管理,無法猜測操作系統將如何並行管理四個磁盤。
我假設這是您需要做的處理的大大簡化的模型。 如果您的描述全部包含,那么真正的解決方案是在編寫測試文件的程序中進行減法!
與在程序中打開文件並一次讀取所有文件相比,將文件進行內存映射甚至更好。 對於程序可用的〜2GB地址空間,〜18MB沒問題。
然后使用strtod
讀取數字並前進指針。
與輸入重定向和scanf
相比,我期望有5-10倍的加速。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.