在处理大量线路时,TMemo的速度很慢 [英] TMemo is painfuly slow when working with large number of lines

查看:118
本文介绍了在处理大量线路时,TMemo的速度很慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在TMemo中有100000行。我想做类似的事情:

I have 100000 lines in a TMemo. I want to do something like:

 for i:= 0 to Memo.Lines.Count-1 do
  Memo.Lines[i]:= SomeTrim(Memo.Lines[i]);

但是速度是每秒0.5行!

but the speed is 0.5 lines per second!!

添加BeginUpdate / EndUpdate之后,我看不到任何速度改进。

After adding BeginUpdate/EndUpdate I don't see any speed improvement.

 Memo.Lines.BeginUpdate;
 for i:= 0 to Memo.Lines.Count-1 do
  Memo.Lines[i]:= SomeTrim(Memo.Lines[i]);
 Memo.Lines.EndUpdate;

我的问题是,为什么BeginUpdate / EndUpdate无法解决问题?

My question is why BeginUpdate/EndUpdate won't help?

推荐答案

TStrings.BeginUpdate / EndUpdate 仅禁止 OnChanging OnChanged 事件。它对内容本身的更改的内部处理没有影响。

TStrings.BeginUpdate/EndUpdate will only prohibit the OnChanging and OnChanged events. It has no influence on the internal handling of the changes to the content itself.

TMemo.Lines 由实现 TMemoStrings 将文本内容存储在Window控件本身中。因此, BeginUpdate / EndUpdate 在这里几乎没有用。

TMemo.Lines is implemented by TMemoStrings which stores the text content in the Window control itself. Thus BeginUpdate/EndUpdate is pretty useless here.

使用本地<$ c $可能会得到更好的结果。 c> TStringList 实例,并使用 Text 属性将数据从 TMemo 复制到 TStringList 并返回。 Text 属性是一次访问 TMemo 的全部内容的最有效方法。

You might get better results by using a local TStringList instance, and using the Text property to copy the data from TMemo to TStringList and back. The Text property is the most efficient way to access the whole content of a TMemo at once.

  lst := TStringList.Create;
  try
    lst.Text := Memo1.Lines.Text;
    for I := 0 to lst.Count - 1 do begin
      lst[I] := SomeTrim(lst[I]);
    end;
    Memo1.Lines.Text := lst.Text;
  finally
    lst.Free;
  end;

注意:一些评论提到使用分配在将内容从备忘录复制到备忘录中时,使用而不是 Text 属性: Assign 是在这种情况下,由于对 TMemoLines Text 属性进行了内部优化,因此速度显着降低。此属性的Getter和Setter使用单个WM_GETTEXT / WM_SETTEXT消息直接访问Windows控件,而 Assign 每行使用一条EM_GETLINE消息进行读取,并使用一系列EM_LINEINDEX,EM_SETSEL ,每行EM_LINELENGTH和EM_REPLACESEL进行写入。一个简单的计时测试表明,以上代码需要大约600毫秒,而将 Text 分配替换为 Assign 调用需要的时间超过11秒!

Note: Some comments mention to use Assign instead of the Text property when copying the content from and to the Memo: Assign is significantly slower in this case due to an internal optimization of the Text property for TMemoLines. The Getter and Setter of this property accesses directly the Windows control with a single WM_GETTEXT/WM_SETTEXT message, while Assign uses one EM_GETLINE message per line for reading and a sequence of EM_LINEINDEX, EM_SETSEL, EM_LINELENGTH and EM_REPLACESEL per line for writing. A simple timing test shows that the above code needs about 600 ms while replacing the Text assignments with Assign calls needs more than 11 seconds!

这篇关于在处理大量线路时,TMemo的速度很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆