Community
Participate
Working Groups
Running eclipse, using the Java Editor: A single key stroke can cause the API Font.getFontData() to be called 13 times. I believe, and many people agree, that this API don't need to be used at all by the StyledText when it's been typed. This API is also overused when we are scrolling the StyledText and selecting text. Try to add system.out.println in the first line of method Font#getFontData, run a selfhosted eclipse, watch the console. I concerned about this problem cause in some platform the performance of this method is very pour if compared with Windows. For example, Motif running on UTF-8. Each Font has 7 FontData, therefore every time I type 'a' in the JavaEditor 91 (7*13) FontData will be loaded. Btw, UTF-8 is the default english encoding for Redhat 8. FontMetrics API is also very used by the StyledText, I believe that the metric information should be cached in the StyledText and update only when the font is changed.
I've locked in the StyledText code to know why getFontData is need, and as far as I understand the code this API is only been used to check the style in the (first) FontData and pick the rigth font (regular/bold) for the GC. I've changed this in the StyledText, I'm attaching my changes in.
Created attachment 2691 [details] Patch for StyledText and other A version of StyledText that doesn't use getFontData.
Felipe found on a particular motif box that calling getFontData a hundred times could take 2 seconds. Typing 10 characters per second, a not so unrealistic rate, would cause 130 calls. Lynne/Knut to investigate and advise. Please let us know what you think of the suggested change. Thanks!
I just realized that I changed a protected method in StyledTextRender (drawLineSelectionBackground), Even though I've already changed DisplayRenderer and PrintRenderer this method is part of StyledText API and may cause problems in anothers implementations of the type (if they exist). Anyhow, Knut & Lynne can take care of this.
Thanks Felipe. We did do a pass on calling getFontData() less awhile ago, but I guess more calls to it leaked into the code. The changes look okay to me, but Knut should verify this. StyledTextRenderer does not have any public API, so the changes won't break anything.
You guys should do this soon (for M5) to give us a nice long time to test it.
Related report [Bug 26057].
From KR: I don't understand the new code in StyledTextRenderer.setLineFont. The purpose of the old code was to avoid setting the font on the GC if it is already set. We basically just used the fontdata to hold the current font style. We probably could have used an int[] argument that gets passed back up or a global variable. The new identity check doesn't make sense to me. I think this test always resolves to true on Windows because getFont always returns a new object. Other platforms probably work the same way. In addition the font that is passed in as currentFont is the gc.getFont, i.e., the font currently set in the GC. So even if we tested equality it would still always resolve to true. The result would be that the font is always set, every time setLineFont is called. If GC.setFont is not expensive on any of the platforms we can just get rid of the passed in Font. From FH: Agreed, to use identity or equality are both wrong... But we should not call GC.setFont all the time, it can be a performance problem. I believe setLine should be something like this: private void setLineFont(GC gc, int style) { if (currentStyle != style) { if (style == SWT.BOLD) { gc.setFont(boldFont); } else if (style == SWT.NORMAL) { gc.setFont(regularFont); } currentStyle = style; //this would be the global variable Knut said. } } Getting rid of passing Font in all those methods makes the code more simple. I've tried this but I was not able to get caret in the right place when moving it over a a bold text.
Changed to cache current font style. Also put in change to minimize the number of times setFont is called when text includes different font styles.