Font scaling performance issue [message #1836456] |
Mon, 04 January 2021 17:45 |
Yann Mortier Messages: 19 Registered: July 2009 Location: Paris FR |
Junior Member |
|
|
Hello,
Happy new year!
I think we found a performance issue with font scaling on large diagrams. After investigation, it seems org.eclipse.gmf.runtime.draw2d.ui.internal.graphics.ScaledGraphics.getCachedFont(FontKey) computes font data too many times.
Firstly here is the test environment:
- Intel Core i7-6820HQ
- 16GB ram available
- Windows 10
- ObeoDesigner Community 11.3 (default configuration Xmx2048m but with Java 14 from AdoptOpenJDK)
We have executed some tests on the attached project.
1. Zoom
To reproduce the issue, import the attached project (01-zoom.test.zip), open the unique diagram, close outline view (in order to not interfere with performance measure) and disable animated zoom in preferences. Do some zoom changes (switch from 5% to 400% many times) to warmup Obeo Designer.
Start VisualVM and start CPU sampler on Obeo Designer Community. Do some zoom changes (switch from 5% to 400% 10 times). Stop the CPU sampler and do a snapshot. In hotspots look for getCachedFont
Attachments:
- 02-getCachedFont.png: cpu times in gmf.ScaledGraphics.getCachedFont when zooming in/out ten times
- 03-Zoom.png: cpu times in ZoomManager.setZoom
In the 4.8 seconds for Zoom, 2.3 seconds are spent with getCachedFont
2. Create element
Zoom out to 25% and add some elements to warmup Obeo Designer.
Start VisualVM and start CPU sampler on Obeo Designer Community. Create 10 new classes quickly on the diagram and wait for the selection of the last created element. Stop the CPU sampler and take a snapshot. In hotspots look for getCachedFont
Attachments:
- 04-getCachedFontAddElement.png: cpu time in gmf.ScaledGraphics.getCachedFont when adding 10 elements
- 05-AddElement.png: cpu time in draw2d.LightweightSystem.EventHandler.handleEvent(Event) when adding 10 elements
In the 10 seconds for adding 10 elements, 4 seconds are spent with getCachedFont
Please, note that CPU time is, in fact, spent in SWT Windows implementation. So, this issue might not be reproducible on another Operating System.
3. Analysis
We have look into ScaledGraphics into draw2d and GMF. The draw2d class do not call Font.getFontData if the font is already in cache but the GMF one always call Font.getFontData.
draw2d.ScaledGraphics.getCachedFont
Font getCachedFont(FontKey key) {
Font font = (Font) fontCache.get(key);
if (font != null) {
return font;
}
key = new FontKey(key.font, key.height);
FontData data = key.font.getFontData()[0];
data.setHeight(key.height);
Font zoomedFont = createFont(data);
fontCache.put(key, zoomedFont);
return zoomedFont;
}
gmf.ScaledGraphics.getCachedFont
Font getCachedFont(FontKey key) {
FontData data = key.font.getFontData()[0];
data.setHeight(key.height);
return FontRegistry.getInstance().getFont(Display.getCurrent(), data);
}
As you can see, Font.getFontData() is always called in the GMF implementation.
4. Solution?
We have tried a patch but we don't know about the implications:
1. Uncomment line 188
private Map fontCache = new HashMap();
2. change getCachedFont to:
Font getCachedFont(FontKey key) {
Font font = (Font) fontCache.get(key);
if (font != null) {
return font;
}
key = new FontKey(key.font, key.height);
FontData data = key.font.getFontData()[0];
data.setHeight(key.height);
Font zoomedFont = FontRegistry.getInstance().getFont(Display.getCurrent(), data);
fontCache.put(key, zoomedFont);
return zoomedFont;
}
The font is not disposed in the dispose method because it is created by FontRegistry.
Then, using a very very very reliable technic (changing class files in gmf.draw2d.ui jar file in OD Community...) we execute the tests above. The diagram is much more responsive and the sampler do not detect any cpu time spent into getCachedFont (it might be too fast for the sampler, the profiler should be used to have better results).
Can you reproduce the issue. Should I open a ticket for Sirius or GMF?
Thanks and have a nice day,
Yann
|
|
|
|
Powered by
FUDForum. Page generated in 0.02851 seconds