Where to look for performance issues

96 views
Skip to first unread message

Lex Trotman

unread,
Jul 1, 2012, 8:33:11 PM7/1/12
to scintilla...@googlegroups.com
Hi Neil and ScintillaGTK experts,

In Geany we are experiencing slowing of performance after a file has
been open and edited all day. The effect is that some screen paints
can be visibly slow.

So far we have measured ScintillaGTK::ExposeTextThis as normally
taking less than 10ms, but when the slowdown is visible sometimes it
can take more than 150ms, and sometimes the normal <10ms. The same
file just open all day but not edited shows about 50ms sometimes.

The file used is just a 500 line Python file, ie nothing special.

We have upgraded Geany to Scintilla 3.2 with no effect.

As we have no expertise in the internals of ScintillaGTK and as it
takes all day for the problem to be reliably visible it is very slow
going trying to find anything.

Can Neil or anyone suggest the most likely places to look and what
methods might be safely used without upsetting the operation of
Scintilla (at the moment we just use a timer and print the time to the
output but that would probably make the whole thing unusable if it was
inside some of the functions that are called millions of times)

Note that profiling isn't useful as it takes so long for the problem
to be visible that all the profiling counters have wrapped around
several times and so the data is meaningless.

Current test bed is Linux XFCE4 with GTK 3.24.10 Glib 2.30.2.

Thanks
Lex

Neil Hodgson

unread,
Jul 1, 2012, 9:31:49 PM7/1/12
to scintilla...@googlegroups.com
Lex Trotman:

> In Geany we are experiencing slowing of performance after a file has
> been open and edited all day. The effect is that some screen paints
> can be visibly slow.
>
> So far we have measured ScintillaGTK::ExposeTextThis as normally
> taking less than 10ms, but when the slowdown is visible sometimes it
> can take more than 150ms, and sometimes the normal <10ms. The same
> file just open all day but not edited shows about 50ms sometimes.

Over that period, I'd suspect memory or resource issues. Check whether there is more memory being used than at the start.

Breaking the 150ms down further into individual methods or lines would help discover the underlying issue. Just breaking the ExposeTextThis time into PaintSelMargin, Paint before painting lines, painting each line, and painting after lines would be useful. Measure time spent in each notification to the host app. Check whether wrap is on - mode wrap can be much slower and memory intensive than normal painting.

Neil

Lex Trotman

unread,
Jul 30, 2012, 10:34:53 PM7/30/12
to scintilla...@googlegroups.com
Hi Neil,

Quick follow up, the problem appears to be due to the use of
INDIC_SQUIGGLE for compile errors and spelling errors, when there is a
significant amount of indicator the performance slows way down.
Switching to INDIC_PLAIN returns performance to normal, but sadly most
users seem to have a preference for wavy error indicators.

One of the Geany team is looking at a more optimised implementation
(for the cairo implementation anyway) and will submit it if
successful.

Cheers
Lex

>
> --
> You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
> To post to this group, send email to scintilla...@googlegroups.com.
> To unsubscribe from this group, send email to scintilla-inter...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/scintilla-interest?hl=en.
>

Neil Hodgson

unread,
Jul 31, 2012, 6:33:11 AM7/31/12
to scintilla...@googlegroups.com
Lex Trotman:

> Quick follow up, the problem appears to be due to the use of
> INDIC_SQUIGGLE for compile errors and spelling errors, when there is a
> significant amount of indicator the performance slows way down.

Its a repeating 4x3 pixel pattern so a pixmap could be created and drawn instead of stroking many lines.

Neil

Lex Trotman

unread,
Jul 31, 2012, 5:31:33 PM7/31/12
to scintilla...@googlegroups.com
Yes, I think thats what is being tried.

Cheers
Lex

>
> Neil

Matthew Brush

unread,
Aug 1, 2012, 7:57:04 PM8/1/12
to scintilla...@googlegroups.com
Hi Neil,

Attached is a fairly-straightforward patch that improves the performance
of the squiggle indicators by around 3-5 times. The commit message has
some details about the changes. The only drawback I can see is that the
squiggles are no longer anti-aliased as they were with the
MoveTo()/LineTo() stuff. It still looks fine to my eyes though, I guess
you can be the judge.

There's a couple of other ways I could see doing this but I was unable
to figure out how to implement them without dropping into Cairo.

Cheers,
Matthew Brush
squiggles.patch

Neil Hodgson

unread,
Aug 2, 2012, 11:32:18 PM8/2/12
to scintilla...@googlegroups.com
Matthew Brush:
 
The only drawback I can see is that the
squiggles are no longer anti-aliased as they were with the
MoveTo()/LineTo() stuff.

   This should really be a new indicator type so that the current antialiased drawing can be used when it is fast enough. One problem with the bitmap code is that for OS X HiDPI mode, it will be displaying 2x2 pixel blocks instead of using the full resolution.

   For maximum intensity, the bitmap should be aligned to the pixel grid (and INDIC_DOTBOX should be fixed to do this) since text and thus the rectangle may be located at fractional pixels. This is done by rounding the rectangle to pixels: rcSquiggle.left = int(rc.left + 0.5); ...

   Approximate antialiasing can still be done with the bitmap and this can make it look heavier although its a question of taste as to the best settings. Here are three versions: the original and with heavy and light antialiasing. http://www.scintilla.org/Squiggles.png

   In the following code, the three alpha values can be modified to change antialiasing and thus visibility. Choosing alphaSide2 to be double alphaSide keeps the line weight even although other choices may work.

PRectangle rcSquiggle = rc;
rcSquiggle.left = int(rc.left + 0.5);
rcSquiggle.right = int(rc.right + 0.5);

int width = Platform::Minimum(4000, rcSquiggle.right - rcSquiggle.left);
RGBAImage image(width, 3, 1.0, 0);
enum { alphaFull = 0xff, alphaSide = 0x1f, alphaSide2=0x3f };
for (int x = 0; x < width; x++) {
switch (x%4) {
case 0:
image.SetPixel(x, 2, fore, alphaFull);
image.SetPixel(x, 1, fore, alphaSide2);
break;
case 1:
image.SetPixel(x, 1, fore, alphaFull);
image.SetPixel(x, 0, fore, alphaSide);
image.SetPixel(x, 2, fore, alphaSide);
break;
case 2:
image.SetPixel(x, 0, fore, alphaFull);
image.SetPixel(x, 1, fore, alphaSide2);
break;
default: // 3
image.SetPixel(x, 1, fore, alphaFull);
image.SetPixel(x, 2, fore, alphaSide);
image.SetPixel(x, 0, fore, alphaSide);
}
}
surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels());

   Neil

Lex Trotman

unread,
Aug 3, 2012, 1:24:14 AM8/3/12
to scintilla...@googlegroups.com
On 3 August 2012 13:32, Neil Hodgson <nyama...@me.com> wrote:
> Matthew Brush:
>
>
> The only drawback I can see is that the
> squiggles are no longer anti-aliased as they were with the
> MoveTo()/LineTo() stuff.
>
>
> This should really be a new indicator type so that the current
> antialiased drawing can be used when it is fast enough. One problem with the
> bitmap code is that for OS X HiDPI mode, it will be displaying 2x2 pixel
> blocks instead of using the full resolution.

Sorry can't test with that platform.

>
> For maximum intensity, the bitmap should be aligned to the pixel grid
> (and INDIC_DOTBOX should be fixed to do this) since text and thus the
> rectangle may be located at fractional pixels. This is done by rounding the
> rectangle to pixels: rcSquiggle.left = int(rc.left + 0.5); ...
>
> Approximate antialiasing can still be done with the bitmap and this can
> make it look heavier although its a question of taste as to the best
> settings. Here are three versions: the original and with heavy and light
> antialiasing. http://www.scintilla.org/Squiggles.png
>

Tried your code below in Geany and the performance is only marginally
slower than the un-antialiased version:

UnAA: ~48ms for re-draw
Below: ~52ms for re-draw
Original: ~320ms for re-draw

(thats showing C++ code with about 9 80 character lines with indic
squiggle (of the 50 on screen), a not unreasonable scenario when
compiling)

Since This pseudo AA version is nearly as fast as non-AA and looks (to
me) as good as the original it seems like a good approach.

Cheers
Lex

Matthew Brush

unread,
Aug 3, 2012, 8:27:20 PM8/3/12
to scintilla...@googlegroups.com
On 12-08-02 10:24 PM, Lex Trotman wrote:
> On 3 August 2012 13:32, Neil Hodgson <nyama...@me.com> wrote:
>> Matthew Brush:
>>
>> The only drawback I can see is that the
>> squiggles are no longer anti-aliased as they were with the
>> MoveTo()/LineTo() stuff.
>>
>> [...]
>>
>> Approximate antialiasing can still be done with the bitmap and this can
>> make it look heavier although its a question of taste as to the best
>> settings. Here are three versions: the original and with heavy and light
>> antialiasing. http://www.scintilla.org/Squiggles.png
> [...]
>
> Since This pseudo AA version is nearly as fast as non-AA and looks (to
> me) as good as the original it seems like a good approach.

+1

Cheers,
Matthew Brush

Neil Hodgson

unread,
Aug 5, 2012, 4:21:11 AM8/5/12
to scintilla...@googlegroups.com
Lex Trotman:
> Since This pseudo AA version is nearly as fast as non-AA and looks (to
> me) as good as the original it seems like a good approach.

Matthew Brush:
> +1

Committed with the name INDIC_SQUIGGLEPIXMAP so that other platforms and existing code will not change. The line weight is between the two examples shown.

Also updated INDIC_DOTBOX to be pixel grid aligned and fixed the right side of INDIC_SQUIGGLE.

Neil
Reply all
Reply to author
Forward
0 new messages