2017-10-28 30 views
4

TMemoに100000行あります。私は次のようなことをしたい:多数の行を扱うとき、TMemoが非常に遅い

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

しかし、速度は毎秒0.5ラインです!

BeginUpdate/EndUpdateを追加しても、スピードの向上は見られません。

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

私の質問はなぜBeginUpdate/EndUpdateが役立たないのですか?

+3

このようなメモをスクロールするユーザーが不十分です。 – Victoria

+0

PS:現在の解決策は、TStringListに行を割り当てて処理し、メモに戻すことです。しかし、なぜBeginUpdateが機能しないのか不思議です。 – Ampere

+0

@Victoria - ユーザーはこれらの行を配置します。通常、私は100行以下を期待しています。私は100000で何が起こるかを調べるためにテストしたかったのです。そして、これが起こります。 – Ampere

答えて

10

TStrings.BeginUpdate/EndUpdateは、OnChangingOnChangedイベントを禁止します。コンテンツ自体の変更の内部処理には影響しません。

TMemo.Linesは、ウィンドウコントロール自体にテキストコンテンツを格納するTMemoStringsによって実装されます。従ってBeginUpdate/EndUpdateはここではかなり役に立たない。

ローカルTStringListインスタンスを使用して、そしてTMemoからTStringListとバックにデータをコピーするTextプロパティを使用して、より良い結果を得る可能性があります。 Textプロパティは、TMemoのコンテンツ全体に一度にアクセスする最も効率的な方法です。

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; 

注:原因TMemoLinesためText財産の内部最適化にAssignが、この場合はかなり遅いです:いくつかのコメントはからとメモにコンテンツをコピーするときに代わりにTextプロパティのAssignを使用するように言及。このプロパティのGetterとSetterは、1つのWM_GETTEXT/WM_SETTEXTメッセージでWindowsコントロールに直接アクセスします。Assignは、1行に1つのEM_GETLINEメッセージを読み取りに使用し、一連のEM_LINEINDEX、EM_SETSEL、EM_LINELENGTH、EM_REPLACESELを書き込みごとに使用します。簡単なタイミングテストでは、上記のコードはTextの割り当てをAssignで置き換えて約600秒が必要であることを示しています。

+5

'Text'プロパティの代わりに' Assign() 'メソッドを使います:' lst.Assign(Memo1.Lines); ... Memo1.Lines.Assign(lst); '行はすでに別々であるため、そのままコピーして、再解析するだけで連結しないでください。つまり、メモリと処理の無駄です。 –

+0

@RemyLebeauそれぞれの行を別々に取得して設定するのは、元のコードが実際に行ったことです。 –

+9

私はそれを認識しています。 Memoの内容をStringListにコピーしてから戻すことを指しています。あなたの答えは、 'Text'プロパティがそれを行うための「最も効率的な」方法だと言いますが、それは遠隔からでも、特に100000行で真実ではありません。 'Text'ゲッタは2パススキャンを実行してメモリを割り当て、コピーします。その後、' Text'セッタは入力を解析して多くの割り当てを行います。他方、 'Assign()'は、はるかに少ない割り当てしか実行せず、1パススキャンを使います。あなた自身のためにプロファイルしてください。 'Assign()'は 'Text'よりも効率的です。 –

関連する問題