2011-11-23 61 views
0

我寫了一個使用Free Pascal和Lazarus IDE的程序。簡而言之,它遞歸地掃描目錄,併爲每個文件「做些東西」(哈希),然後將哈希值和文件名輸出到一個StringGrid中,每個後續文件都刷新一次。爲什麼我的StringGrid在成千上萬的條目後似乎變慢了?免費Pascal

它可以很好地處理多達幾千個文件,但是當你達到數萬個時,它確實會變慢,每半秒處理一個文件,即使它只是一個幾Kb的小文件。

下面是代碼的主要部分。任何人都可以看到爲什麼我的程序在網格中的文件數量超過數萬時變慢?

procedure TForm1.HashFile(FileIterator: TFileIterator); 
var 
    SizeOfFile : int64; 
    NameOfFileToHash, fileHashValue, PercentageProgress : string; 
    FI : TFileIterator;      //File Iterator class 
    SG : TStringGrid; 

begin 
    FI := TFileIterator.Create; 
    SG := TStringGrid.Create(self); 
    SizeOfFile := 0; 
    fileHashValue := ''; 

    if StopScan = FALSE then      // If Stop button clicked, cancel scan 
    begin 
    NameOfFileToHash := (FileIterator.FileName); 
    SizeOfFile := FileSize(NameofFileToHash); 
    StatusBar1.SimpleText := 'Currently Hashing: ' + NameOfFileToHash; 
    fileHashValue := CalcTheHashFile(NameOfFileToHash); // Custom function, see below 

    // Now lets update the stringgrid and text fields 

    // StringGrid Elements: 
    // Col 0 is FileCounter. Col 1 is File Name. Col 2 is Hash 
    StringGrid1.rowcount:= FileCounter+1; 
    StringGrid1.Cells[0,FileCounter] := IntToStr(FileCounter); 
    Stringgrid1.Cells[1,FileCounter] := NameOfFileToHash; 
    Stringgrid1.Cells[2,FileCounter] := UpperCase(fileHashValue); 

    // Dynamically scroll the list so the user always has the most recently hashed 
    // file insight and expand the columns in lie with their content width 

    StringGrid1.row := FileCounter; 
    StringGrid1.col := 1; 
    StringGrid1.AutoSizeColumns; 

    // Progress Status Elements: Most of these vars are global vars 

    NoOfFilesExamined.Caption := IntToStr(FileCounter); 
    PercentageProgress := IntToStr((FileCounter * 100) DIV NoOfFilesInDir2); 
    Edit1.Caption := PercentageProgress + '%'; 
    TotalBytesRead := TotalBytesRead + SizeOfFile; 
    edtTotalBytesExamined.Caption := FormatByteSize(TotalBytesRead); 

    Application.ProcessMessages; 
    FileCounter := FileCounter+1; 
    end; 
    SG.Free; 
    FI.Free; 
end; 

完整的源代碼可以從我的SourceForge的網頁,https://sourceforge.net/projects/quickhash/在「文件」 - >「源代碼」,如果你需要的。

任何幫助表示讚賞

特德

回答

5

也是一個Delphi的傢伙兩件事情我彈出。 AutoSizeColumns。如果你幸運的話,它什麼都不做。如果它正沿着10,000行的所有列向前推進,則每更新一次並執行GetTextLength以查看是否適合,然後重新繪製網格....

因此,作業1將預設一些列大小並對其進行註釋。 最多隻需掃描一次即可。

誰想要一次查看所有10,000 +行?

我想我會把它們流出來存檔,並顯示最後1頁完整的表明進度。然後,我會使用簡單的獲取頁面完整場景來從文件中驅動我的用戶界面。 取決於您對數據所做的操作,但您可以重新加載文件以進一步分析,對變化進行比較。

即使你在內存中堅持有一個TList? THashRecord。然後從那裏開動你的顯示器,那麼你將有機會。

+0

HiTaking的自動大小真的幫助!在我到目前爲止的測試中,速度提高了約30%,或者換句話說,當我添加該功能時,它似乎已經減慢了30%,但我只是沒有意識到這是特定的特徵。 –

+0

我發現了一個艱難的方式。 –

1

此外,有某種對於大多數可視化組件的方法做批量更新,這樣的事情:

Try 
    Grid1.BeginUpdate; 
    for Row := low(inputArray) to high(InputArray) do 
    Grid1.Append(InputArray[Row].data); 
Finally 
    Grid1.EndUpdate; 
end; 

以上顯然是僞代碼,但搜索方法對組件像BeginUpdate/EndUpdate。使用這些將防止每一行的無故處理。即使您希望在填充時更新顯示,您也可以每隔10或100行執行一次,而不是每行都執行一次。 (很明顯,您可以使用VirtualListbox等,而不是像其他人所提到的那樣爲每個行提供組件)。

相關問題