http://bugs.winehq.org/show_bug.cgi?id=30627
Bug #: 30627 Summary: Appending text to a large richedit is very slow Product: Wine Version: 1.5.3 Platform: x86 OS/Version: Linux Status: NEW Severity: enhancement Priority: P2 Component: richedit AssignedTo: wine-bugs@winehq.org ReportedBy: dank@kegel.com Classification: Unclassified
Although the pathological case reported in bug 30614 is now fixed, all is not yet well.
When repeatedly appending lines, builtin riched20 starts out about 3x slower than native, and at 40k lines, is about 10x slower than native. This is painful for long-running apps that use richedit for verbose logs.
(Measured with the attached program and today's git on my i5, appending 1000 lines to an empty richedit control takes builtin hidden: 907 ms builtin visible: 4862 ms native hidden: 368 ms native visible: 4530 ms Appending 1000 lines to a richedit control which already contains 40000 lines takes: builtin hidden: 22169 ms builtin visible: 33002 ms native hidden: 1750 ms native visible: 4807 ms )
Building wine's riched20 with -O1 -fno-inline and profiling with 'perf' shows 62.60% ME_WrapMarkedParagraphs 12.07% ME_PaintContent 9.99% ME_InvalidateMarkedParagraph at 50k lines.
Initial inspection seems to show that most of the time in ME_WrapMarkedParagraphs is in the function itself, not in any called functions.
Adding trace statements to all callers of ME_WrapMarkedParagraphs, I see one call during EM_EXSETSEL: ME_Repaint Calling ME_WrapMarkedParagraphs and four calls during EM_REPLACESEL: ME_UpdateRepaint Calling ME_WrapMarkedParagraphs ME_UpdateScrollBar Calling ME_WrapMarkedParagraphs ME_Repaint Calling ME_WrapMarkedParagraphs ME_UpdateScrollBar Calling ME_WrapMarkedParagraphs
This is the case whether the window is hidden or not.
Bug 13355 (which Dylan says is separate, since it's about richedit being slow on a single large call to WM_SETTEXT) suggests in comment 14 ways to remove some redundant calls to ME_WrapMarkedParagraphs, and to let one of them return early.
In addition to those ideas, for this bug, it would be useful if ME_WrapMarkedParagraphs (and ME_InvalidateMarkedParagraph) could avoid making a linear scan across all paragraphs.