2012-09-07 52 views
1

已搜索,但似乎找不到我所需的數據。在C++中使用快速差異實現來獲取大文件中行差異的數量

我正在尋找一個快速的C++相當於運行以下命令:

diff file1.log file2.log | wc -l 

目前,我使用的文件的管道,以運行在命令行差異,但是我需要做的這是一個大型的多重嵌套循環,需要比我預期的更長的時間。 diff diff的文件大約150-200mb每個,每個差異大約需要1-2分鐘。

有沒有更快的解決方案,可以由C++推出?

這是我目前的調用它的方法:

static std::string run_cmd(std::string in) 
{ 
    // run command 
    FILE* pipe = popen(in.c_str(), "r"); 
    if (!pipe) return "err"; 

    char buff[128]; 
    std::string res = ""; 
    while (!feof(pipe)) 
    { 
    if (fgets(buff, 128, pipe) != NULL) 
     res += buff; 
    } 
    pclose(pipe); 
    return res; 
} 

// diff 2 given files and return line number differences 
std::string fileDiff(std::string file1, std::string file2) 
{ 
    std::string f1 = base + file1; 
    std::string f2 = base + file2; 
    std::string cmd = "diff " + f1 + " " + f2 + " | wc -l"; 

    std::string res = run_cmd(cmd); 
    if (res == "err") 
    return "E: Diff on [" + f1 + "] and [" + f2 + "]"; 

    return res; 
} 

編輯:

什麼,我基本上做的是日誌代碼覆蓋率。我已經將日誌記錄插入到我正在工作的代碼庫的每個角落,並將每個運行寫入其自己的日誌文件。我試圖通過不將它們包括在構造函數,循環等中來最小化寫入懲罰,並緩衝了實際的寫入過程。

我通常花了大約10分鐘的時間運行程序。隨着我添加日誌記錄和差異調用它的規模擴大到約1天。

我只關心這種情況下線條差異的數量,因爲它是在遺傳算法中提供適應度函數。迭代之間的執行路徑的傳播在這一點上很重要。

+1

你可能不會比diff命令獲得更好的性能。它已經以編譯語言構建。 –

+1

我認爲你唯一希望做得更快的方法是利用特定的文件結構。例如,如果您知道您的差異只會出現在特定列中,則可以減少要比較的文本數量。 –

+0

技嘉的四分之一不會是一個噴嚏來區分。您可能正在嘗試更有效地解決問題的錯誤解決方案。你區別他們的原因是什麼? –

回答

2

啓動外部過程很快。在每個文件1-2分鐘,過程產生的開銷是一個微不足道的小部分。您必須限制1)diff命令的執行或2)管道輸出數據的低效讀取和存儲。嘗試在shell中運行diff命令並輸出到文件中。它快多快?如果不是,那麼1)。如果是這樣,那麼2)。

我對Unix管道知之甚少,但128字節的緩衝區聽起來很小。 diff命令是舊的並被廣泛使用,所以不太可能編寫更快的版本。

+0

左字段的另一個答案:是否有可能可以替換這部分你的程序有一個shell腳本?如果你使用xargs等,你可以依靠shell快速實現管道。 – japreiss

+0

既然你接受了我的回答,我對你發現的東西很感興趣。任何更新? – japreiss

1

我可以看到兩種可能性。

一個是簡化問題。 diff做了很多工作來找到將一個文件轉換爲另一個文件的最小編輯集。如果您只想知道兩個文件之間有多少行不同,並且不關心如何轉換爲另一個文件,您可以通過在每個文件中構建一組行來獲得某些速度,並在它們之間獲得set_symmetric_difference的大小。

第二個是,如果你正在尋找(例如)最相似或最不相似的文件,那麼現在你可能重新在每個文件和其他文件之間進行差異化。換句話說,你有一個二次問題,並給出N個文件,你重新讀取每個文件N次。

根據您要完成的操作和文件數量,您很可能只能讀取一次每個文件。例如,如果你對每一行進行散列,並且只存儲一組散列,那麼你可能會立即將所有文件的數據放入內存中,所以操作的二次部分可以完全在內存中發生,而不是重讀每一個文件倍。