Delphi循环速度问题

标签 delphi loops for-loop performance

有没有更快的方法?我基本上需要一次将 AA-ZZ 添加到数千条记录中。

仅列出 35 项就需要相当长的时间才能完成,更不用说列出 1000 项了。


procedure Tmainform.btnSeederClick(Sender: TObject);
var
  ch,ch2:char;
  i:integer;
  slist1, slist2:TStrings;
begin
  slist1:= TStringList.Create;
  slist2:= TStringList.Create;
  slist1.Text :=queuebox.Items.Text;
  for ch := 'a' to 'z' do
    begin
      for ch2 := 'a' to 'z' do
        begin
          //<p></p>

      for I := 0 to slist1.Count - 1 do
        begin
        application.ProcessMessages; // so it doesn't freeze the application in long loops.  Not 100% sure where this should be placed, if at all.
         sleep(1);  //Without this it doesn't process the cancel button.
         if cancel then Break; 
         slist2.Add(slist1.Strings[i]+ch+ch2);
        end;
    end;
end;
insertsingle(slist2,queuebox);
freeandnil(slist1);
freeandnil(slist2);

结束;

感谢您的帮助

最佳答案

您的代码存在一些明显的问题。

首先,您会浪费大量 CPU 周期来一遍又一遍地计算相同的值。 AA..ZZ 值不会改变,因此无需一遍又一遍地构建它们。尝试这样的操作:创建第三个 TStringList。用双循环遍历并用所有可能的 AA..ZZ 排列填充它。完成后,循环遍历此预先计算的字符串列表并将其与 slist1 中的值合并。您应该会看到一个相当大的提升。

(或者,如果时间绝对宝贵,请编写一个小程序来计算排列列表并将其保存到文本文件中,然后将其作为可以在运行时加载的字符串资源编译到您的应用程序中。)

其次,这可能就是要你命的原因,你不应该在最里面的循环中使用 ProcessMessages 和 Sleep 调用。 Sleep(1); 听起来像是“ sleep 1 毫秒”,但 Windows 不提供这种精度。您最终得到的是“ sleep 至少 1 毫秒”。它会释放 CPU,直到 Windows 恢复使用它,这通常大约为 16 毫秒。因此,您要在一个非常紧密的循环中添加 16 毫秒的延迟(加上 ProcessMessages 所需的时间),该循环可能只需要几微秒即可执行其余代码。

如果您需要类似的东西来保持 UI 响应,它应该位于最外层循环中,而不是内部循环中,并且您甚至可能不需要每次迭代都运行它。尝试类似 if ch mod 100 = 0 then//sleep and process messages here。克雷格建议将此任务移至工作线程也会有所帮助,但前提是您对线程有足够的了解才能正确完成它。它们可能很棘手。

关于Delphi循环速度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2098966/

相关文章:

delphi - 创建一个接受 .PNG 图像作为 Glyph 的按钮

javascript - 按长度过滤国家名称

for 循环内的 JavaScript setTimeout 函数仅发生一次

for-loop - For循环不推断无符号整数

Javascript - 多次循环同一数组

delphi - 打开表单时显示消息(设计器时间)

Delphi - 从应用程序捕获所有action.onexecute

delphi - 将字符数组转换为字符串?

javascript - .splice() 从数组中移除 2 个对象而不是 1 个

javascript - HTML 标签在另一个标签内循环