2011-11-23 65 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等,而不是像其他人所提到的那样为每个行提供组件)。

相关问题