Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 320135 - [painting] "Show whitespace character" option makes the editor very slow on Mac
Summary: [painting] "Show whitespace character" option makes the editor very slow on Mac
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.6   Edit
Hardware: PC Mac OS X
: P3 normal (vote)
Target Milestone: 3.7   Edit
Assignee: Scott Kovatch CLA
QA Contact: Silenio Quarti CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-16 14:05 EDT by Lucas Galfaso CLA
Modified: 2022-02-04 03:16 EST (History)
7 users (show)

See Also:


Attachments
Four thread dumps when performing these actions (4.59 KB, application/x-gzip)
2010-07-19 09:59 EDT, Lucas Galfaso CLA
no flags Details
Potential fix (18.00 KB, patch)
2010-07-19 20:34 EDT, Scott Kovatch CLA
no flags Details | Diff
Better fix (7.48 KB, patch)
2010-07-20 20:57 EDT, Scott Kovatch CLA
no flags Details | Diff
patch (6.26 KB, patch)
2010-07-21 10:51 EDT, Silenio Quarti CLA
no flags Details | Diff
final patch (4.74 KB, patch)
2010-07-21 17:12 EDT, Scott Kovatch CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Lucas Galfaso CLA 2010-07-16 14:05:19 EDT
Build Identifier: 20100617-1415

Enabling the option "Show whitespace character" makes the editor very slow on Mac. Did not tested this on other platforms. The editor is very responsive if this option is off. Using Eclipse Cocoa 64bit version

Reproducible: Always

Steps to Reproduce:
1.Enable "Show whitespace character"
2. Try to use the editor
Comment 1 Remy Suen CLA 2010-07-16 16:02:07 EDT
Likely an SWT an issue but will let Text assess the matter. Do you have this problem with the Carbon build?
Comment 2 Lucas Galfaso CLA 2010-07-17 15:34:45 EDT
I tested this with
Cocoa 64bit
Cocoa 32bit
Carbon 32bit

The issue is very prominent on both Cocoa versions (the editor it is close to unusable with this flag on) and less prominent on Carbon 32bit (it is usable in this environment with this flag on, but not even close to as smooth as with this flag off)

In all cases, when this flag is off, the scrolling and the editor itself is very responsive.
Comment 3 Dani Megert CLA 2010-07-19 05:14:53 EDT
- Which editor (text, Java, ...)?
- How big is the file?
- "very slow/responsive" is very subjective. Can you be a bit more precise.
- If it's really very slow, please make several stack dumps and attach them
  here.
Comment 4 Lucas Galfaso CLA 2010-07-19 09:57:01 EDT
I tested this with a relatively small text file (less than 100 lines and less than 10k bytes in total)
Eclipse 64bit Cocoa built 20100617-1415

Test environment: 2.5 GHz Core 2 duo, 4 GB
 I made no tweaks whatsoever to the eclipse.ini nor any other configuration file


Here are the statistics on some simple action:
  - When in another application, and switching to Eclipse, waiting until the screen is refreshed: 1.2 seconds
  - In the text editor Page down: 1.2 seconds
  - Selecting the entire text in the file: 1.5 seconds
  - Moving one line up: 1.3 seconds
  - Undo typing one line: 0.8 seconds


Did the same thing with a file that is 5 times bigger, the time that it took to do the same actions was about 3 times worst for most actions.

With the "show whitespace" flag off, the response time was so fast I was not able to time it.
Comment 5 Lucas Galfaso CLA 2010-07-19 09:59:51 EDT
Created attachment 174618 [details]
Four thread dumps when performing these actions
Comment 6 Dani Megert CLA 2010-07-19 11:03:11 EDT
Looks like getting the font metrics is slow.

>at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
>at org.eclipse.swt.internal.cocoa.NSMutableAttributedString.setAttributedString(NSMutableAttributedString.java:61)
>at org.eclipse.swt.graphics.GC.getFontMetrics(GC.java:2537)
Comment 7 Scott Kovatch CLA 2010-07-19 16:20:41 EDT
I have what looks like a good fix. It's not necessary to haul in the text layout engine for font metrics.
Comment 8 Scott Kovatch CLA 2010-07-19 20:34:35 EDT
Created attachment 174692 [details]
Potential fix

Rewrite of string drawing to not use a layout manager. For simple string drawing it's not necessary.
Comment 9 Martin Fleurke CLA 2010-07-20 08:31:00 EDT
Bug occurs also on Linux (Ubuntu 10.04 LTS, Eclipse Helios), so not Mac related.

Performance increases when you make the visible part of the editor smaller (resize eclipse or the editor pane).
Comment 10 Martin Fleurke CLA 2010-07-20 08:53:48 EDT
And if you type outside php tags, there is no problem.
Comment 11 Dani Megert CLA 2010-07-20 08:56:12 EDT
The fix looks Mac specific. Maybe you are seeing bug 246196?
Comment 12 Dani Megert CLA 2010-07-20 08:56:42 EDT
And there's bug 26080 for QNX.
Comment 13 Martin Fleurke CLA 2010-07-20 09:28:36 EDT
When I uncheck the 'show whitespace', the problem is gone. Typing is fast again. So it seems this is the same bug.
Comment 14 Remy Suen CLA 2010-07-20 09:31:08 EDT
(In reply to comment #13)
> When I uncheck the 'show whitespace', the problem is gone. Typing is fast
> again. So it seems this is the same bug.

But this bug is for the problem (and fix) on Macs. You are using Linux. The backend for this particular bug is not platform-agnostic.

The symptoms may be identical but the fix is not.
Comment 15 Martin Fleurke CLA 2010-07-20 10:28:25 EDT
That is correct. So I can file a new bug, or this bug can be expanded.

I.m.h.o. a new bug would be appropriate if the cause of the bug under linux and mac is totally different. I think this needs further investigation; having a patch for Mac does not automatically mean that the code is unrelated. There might be similar code for Linux. But I haven't seen any Eclipse code yet, so I can't tell.
But if you (or Scott) prefers a new bug, I'm happy to create one.
Comment 16 Scott Kovatch CLA 2010-07-20 12:05:52 EDT
(In reply to comment #15)

> I.m.h.o. a new bug would be appropriate if the cause of the bug under linux and
> mac is totally different. I think this needs further investigation; having a
> patch for Mac does not automatically mean that the code is unrelated. There
> might be similar code for Linux. But I haven't seen any Eclipse code yet, so I
> can't tell.
> But if you (or Scott) prefers a new bug, I'm happy to create one.

Yes, please file a new bug. I'm not that fluent in GTK, so it will likely need its own investigation. That said, if you are seeing this in both platforms there's probably some code that needs to change in both the SWT and the text editor.

My patch shows definite improvements in scrolling and drawing on OS X Cocoa, but it doesn't make the difference from not having the whitespace there zero. I also didn't look at WhitespaceCharacterPainter to see if there were any improvements to be had there.
Comment 17 Silenio Quarti CLA 2010-07-20 18:07:45 EDT
(In reply to comment #8)
> Created an attachment (id=174692) [details]
> Potential fix
> Rewrite of string drawing to not use a layout manager. For simple string
> drawing it's not necessary.

This is how GC drew/measured strings up to revision 1.71. Take a look a bug#270531 and bug#290373. I think this patch will introduce those bugs back.
Comment 18 Scott Kovatch CLA 2010-07-20 18:29:57 EDT
(In reply to comment #17)
> (In reply to comment #8)
> > Created an attachment (id=174692) [details] [details]
> > Potential fix
> > Rewrite of string drawing to not use a layout manager. For simple string
> > drawing it's not necessary.
> 
> This is how GC drew/measured strings up to revision 1.71. Take a look a
> bug#270531 and bug#290373. I think this patch will introduce those bugs back.

I wondered about that too, but the root problem in 1.71 was getFontMetrics, and in particular, the fact that NSFont methods that give you the ascender and descender are almost always wrong -- you have to measure a string and compute it.

This patch doesn't put the old code back -- it works backwards from the size of the string like we do now. I do need to use NSFont.descender(), which I have found so far to be always correct.
Comment 19 Scott Kovatch CLA 2010-07-20 20:07:07 EDT
(In reply to comment #17)

> This is how GC drew/measured strings up to revision 1.71. Take a look a
> bug#270531 and bug#290373. I think this patch will introduce those bugs back.

Damn. Bug 270531 has defeated me. The string measurements calculated by NSAttributedString/NSString is way off compared to what TextLayout calculates, using NSLayoutManager. And there's no way I'm going to rewrite TextLayout.

Nevertheless, I still think we could improve GC.getFontMetrics() to not make so many attributed strings, since the average width isn't going to change for a given font. Maybe we can cache the average width in the font somehow.
Comment 20 Scott Kovatch CLA 2010-07-20 20:57:30 EDT
Created attachment 174811 [details]
Better fix

Fix caches average char width so we don't create an NSAttributedString, char array and NSString on every call to GC.getFontMetrics.

Also adds fix for bug 276644, by calling setUsesScreenFonts(false) on the layout managers.
Comment 21 Dani Megert CLA 2010-07-21 04:33:47 EDT
>That said, if you are seeing this in both platforms
>there's probably some code that needs to change in both the SWT and the text
>editor.
We could probably cache the GC's font metrics but:
- Shouldn't the GC do that for me? Currently a new font metrics is created on 
  each call to GC.getFontMetrics() but that is not specified in its Javadoc.
- With each draw event we get a new GC where we have to update the cache. SWT 
  could be smarter to reuse the font metrics and set it to the new GC to even 
  further cache the info. See also bug 26080 where something along that lines
  has been suggested.
Comment 22 Silenio Quarti CLA 2010-07-21 10:51:33 EDT
Created attachment 174860 [details]
patch

Looking at our patch made me realize that the code in GC.textExtent() should be calling GC.createString() with false as the draw flag.   If we make that change, your patch would be wrong.   If I understand correctly, the changes you made in createString(), your to avoid the extra work done for delimiters and tabs when calculating the font metrics.  This patch should have the same effect and also improve the performance of GC.textExtent().
Comment 23 Silenio Quarti CLA 2010-07-21 10:57:50 EDT
I forgot to mentioned. The change to call setUsesScreenFont() makes the line for print margin be wrong for Monaco 11 (See bug#29073).
Comment 24 Scott Kovatch CLA 2010-07-21 12:11:53 EDT
(In reply to comment #21)
> We could probably cache the GC's font metrics but:
> - Shouldn't the GC do that for me? Currently a new font metrics is created on 
>   each call to GC.getFontMetrics() but that is not specified in its Javadoc.
> - With each draw event we get a new GC where we have to update the cache. SWT 
>   could be smarter to reuse the font metrics and set it to the new GC to even 
>   further cache the info. See also bug 26080 where something along that lines
>   has been suggested.

On second look I think we could be more aggressive about caching the font metrics. For any given font the values won't change after we calculate them once, so yes, we should be able to cache an entire FontMetrics object in the Font. There's going to be some hit in getting the ascent and descent of that string. That might be enough to make a performance win by itself.
Comment 25 Scott Kovatch CLA 2010-07-21 14:25:33 EDT
(In reply to comment #23)
> I forgot to mentioned. The change to call setUsesScreenFont() makes the line
> for print margin be wrong for Monaco 11 (See bug#29073).

This seems to be happening for me whether setUsesScreenFont is on or off. I'll have to see if there's a problem with the font metric caching.
Comment 26 Scott Kovatch CLA 2010-07-21 17:08:10 EDT
(In reply to comment #25)
> (In reply to comment #23)
> > I forgot to mentioned. The change to call setUsesScreenFont() makes the line
> > for print margin be wrong for Monaco 11 (See bug#29073).

I've opened up a can of worms with the whole setUsesScreenFont thing, so I'm leaving it out for now. It's not relevant to this bug anyway. Bug 276644 tracks that.
Comment 27 Scott Kovatch CLA 2010-07-21 17:12:00 EDT
Created attachment 174921 [details]
final patch

Added FontMetrics caching to the Font object. This seems to be helping for me.
Comment 28 Silenio Quarti CLA 2010-07-21 18:13:40 EDT
Code seems good to me. But the line 

attribStr.initWithString(NSString.stringWith(s), dict);

should reassign attribStr to be in the safe side. I have seem cases where the init() methods return a different object than "self" and that really cause problems.
Comment 29 Scott Kovatch CLA 2010-07-21 18:19:34 EDT
(In reply to comment #28)
> Code seems good to me. But the line 
> 
> attribStr.initWithString(NSString.stringWith(s), dict);
> 
> should reassign attribStr to be in the safe side. I have seem cases where the
> init() methods return a different object than "self" and that really cause
> problems.

Good point. I'll just combine it all into one call like we do in createString -- that's what I intended to do in the first place.
Comment 30 Scott Kovatch CLA 2010-07-21 18:22:40 EDT
Fixed > 20100721. We may want to consider this for 3.6.1; it should provide a general performance boost.
Comment 31 Scott Kovatch CLA 2010-07-21 20:13:19 EDT
.
Comment 32 Martin Fleurke CLA 2010-07-22 04:08:24 EDT
Bug 320595 has been created for the same issue on Linux.
Comment 33 Dani Megert CLA 2010-07-22 04:36:07 EDT
> We may want to consider this for 3.6.1;
Sounds good to me.
Comment 34 Paul Serby CLA 2011-04-20 11:46:18 EDT
I'm getting problems of a similar nature in 3.6.2. 

https://bugs.eclipse.org/bugs/show_bug.cgi?id=323401

Could this be related?
Comment 35 Gregor Dschung CLA 2022-02-04 03:16:33 EST
I can confirm enabling "Show whitespace characters" slows down Eclipse 2021-03 (I haven't updated yet) on macOS 11.6.2.