如何在扫描文件夹/子文件夹/文件时降低CPU使用率?

Mar*_*cel 6 delphi

我开发了一个应用程序,它基本上扫描文件或文件列表的所有位置.当我扫描像10 000个文件和子文件这样的小文件夹时没有问题.但是当我扫描我的整个用户文件夹超过10万个项目时,我的处理器非常沉重.它占用了我处理器功耗的40%左右.

有没有办法优化此代码,以便它使用更少的CPU?

procedure GetAllSubFolders(sPath: String);
var
  Path: String;
  Rec: TSearchRec;
begin
  try
    Path := IncludeTrailingBackslash(sPath);
    if FindFirst(Path + '*.*', faAnyFile, Rec) = 0 then
      try
        repeat
          Application.ProcessMessages;
          if (Rec.Name <> '.') and (Rec.Name <> '..') then
          begin
            if (ExtractFileExt(Path + Rec.Name) <> '') And
              (ExtractFileExt(Path + Rec.Name).ToLower <> '.lnk') And
              (Directoryexists(Path + Rec.Name + '\') = False) then
            begin
              if (Pos(Path + Rec.Name, main.Memo1.Lines.Text) = 0) then
              begin
                main.ListBox1.Items.Add(Path + Rec.Name);
                main.Memo1.Lines.Add(Path + Rec.Name)
              end;
            end;

            GetAllSubFolders(Path + Rec.Name);
          end;
        until FindNext(Rec) <> 0;
      finally
        FindClose(Rec);
      end;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我的应用程序搜索所选文件夹和子文件夹中的所有文件,压缩它们并将它们复制到您指定的其他位置.

Application.ProcessMessages命令用于确保应用程序看起来不会挂起并且用户将其关闭.因为例如找到100 000个文件可能需要一个小时左右......

我担心处理器的使用情况,内存并没有真正受到影响.

注意:备忘录是为了确保未选择两次相同的文件.

Dav*_*nan 17

我看到以下性能问题:

  1. 打电话Application.ProcessMessages有点贵.您正在轮询消息而不是使用阻塞等待,即GetMessage.除了性能问题之外,使用Application.ProcessMessages通常表明由于各种原因设计不佳,并且通常应该避免需要调用它.
  2. 非虚拟列表框对很多文件执行得很糟糕.
  3. 使用备忘录控件(GUI控件)来存储字符串列表非常昂贵.
  4. 每次添加到GUI控件时,它们都会更新和刷新,这非常昂贵.
  5. 评估Memo1.Lines.Text非常昂贵.
  6. 使用Pos同样非常昂贵.
  7. 使用DirectoryExists昂贵且虚假.搜索记录中返回的属性包含该信息.

我会做出以下更改:

  • 将搜索代码移动到一个线程中以避免需要ProcessMessages.您需要设计一些方法将信息传输回主线程以便在GUI中显示.
  • 使用虚拟列表视图显示文件.
  • 将要搜索重复项的文件列表存储在字典中,以便O(1)查找.注意文件名不区分大小写,这个问题到目前为止你可能已经忽略了.这取代了备忘录.
  • 通过使用检查项目是否是目录Rec.Attr.那是检查Rec.Attr and faDirectory <> 0.