簡體   English   中英

在C ++中優化IO

[英]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只是花費大量時間。

您可以在scanf上進行很大的改進,因為可以保證文件的格式。 由於您確切地知道格式是什么,因此您不需要進行太多的錯誤檢查。 另外,printf會在新行上轉換為適合您平台的換行符。

我使用了與本SPOJ論壇帖子中類似的代碼(請參閱本頁面后面的 nosy帖子),以在讀取整數區域中獲得相當大的加速。 您將需要對其進行修改以處理負數。 希望它也會為您提供一些有關如何編寫更快的printf函數的想法,但我將從替換scanf開始,看看能為您帶來多大的幫助。

正如您所建議的,問題在於讀取所有這些數字並將其從文本轉換為二進制。

最好的改進是從任何將二進制數生成的程序中寫出數字。 這將大大減少必須從磁盤讀取的數據量,並略微減少從文本轉換為二進制文件所需的時間。

您說2,000,000個數字占用18MB =每個數字9個字節。 這包括空格和行標記的結尾,因此聽起來很合理。

將數字存儲為4字節整數將減少必須從磁盤讀取的數據量的一半。 在節省格式轉換的同時,可以預期性能會提高一倍。

由於您需要更多,因此需要更根本的東西。 您應該考慮將數據文件拆分為單獨的文件,每個文件都放在自己的磁盤上,然后在自己的進程中處理每個文件。 如果您有4個核心並將處理分成4個獨立的進程,並且可以連接4個高性能磁盤,那么您可能希望性能再提高一倍。 現在的瓶頸是操作系統磁盤管理,無法猜測操作系統將如何並行管理四個磁盤。

我假設這是您需要做的處理的大大簡化的模型。 如果您的描述全部包含,那么真正的解決方案是在編寫測​​試文件的程序中進行減法!

與在程序中打開文件並一次讀取所有文件相比,將文件進行內存映射甚至更好。 對於程序可用的〜2GB地址空間,〜18MB沒問題。

然后使用strtod讀取數字並前進指針。

與輸入重定向和scanf相比,我期望有5-10倍的加速。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM