Great, thanks Danny, I’ll check it out and let you know how it goes


From: Danny Gonzalez <danny.gonza...@screamingfrog.co.uk>
Date: Thursday, 6 February 2020 at 17:27
To: Ed Kennard <e...@kennard.net>
Cc: "openjfx-dev@openjdk.java.net" <openjfx-dev@openjdk.java.net>
Subject: Re: TableView with many columns poor ui performance

Hi Ed,

I have submitted a pull request and the branch is here:
https://github.com/screamingfrog/jfx/tree/listeners_optimisation


Danny




On 6 Feb 2020, at 09:50, Ed Kennard <e...@kennard.net<mailto:e...@kennard.net>> 
wrote:

Hi Danny,

This is great news, I've previously written about perf  issues with TableView, 
do you have a branch I could try out which is rebased off current jfx master?



On 06/02/2020, 10:40, "openjfx-dev on behalf of Danny Gonzalez" 
<openjfx-dev-boun...@openjdk.java.net<mailto:openjfx-dev-boun...@openjdk.java.net>
 on behalf of 
danny.gonza...@screamingfrog.co.uk<mailto:danny.gonza...@screamingfrog.co.uk>> 
wrote:

   Hi,

   We have been struggling with our migration from Java 8 to Java 11 due to 
various issues we are having with TableView. The main issue is the general UI 
lag and slow TableView scroll performance.

   For context here some links around the issues:

   TableView has a horrific performance with many columns #409
   https://github.com/javafxports/openjdk-jfx/issues/409#event-2206515033

   JDK-8088394 : Huge memory consumption in TableView with too many columns
   https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8088394

   JavaFX TreeTableView slow scroll performance
   https://bugs.openjdk.java.net/browse/JDK-8166956

   TableRowSkinBase fails to correctly virtualise cells in horizontal direction
   https://bugs.openjdk.java.net/browse/JDK-8185887

   OpenJFX mailing list thread: TableView slow vertical scrolling with 300+ 
columns
   https://mail.openjdk.java.net/pipermail/openjfx-dev/2020-January/024780.html


   We have a TableView that is being populated with rows dynamically around the 
rate of 2 rows per second. The issue we are experiencing is the lagginess of 
the UI when these rows are being inserted. TableViews with fewer columns don’t 
seem to exhibit the behaviour quite as badly.

   I can see that there was an optimisation in Java 8 that would alleviate the 
TableView performance issue. If you used a fixed cell size in your TableView, a 
bit of optimisation code in TableRowSkinBase.isColumnPartiallyOrFullyVisible 
would  only render the visible columns. This code, as has been documented in 
the first link above, used to work in Java 8 but not now in Java 11. It also 
has a bug where the visible columns calculation is incorrect and instead 
calculates the visibility on the whole width of the TableView rather than the 
visible columns. I have tried fixing this up, and even with this code fixed, it 
brings in other issues where resizing the TableView results in blank columns.

   I have done some testing and can see that the main issues with the slow down 
is to do with the thousands of listeners that are being removed in TableView 
when you add rows or scroll. It is taking up to 60% of the JavaFX Application 
thread.
   For whatever reason the amount of listeners registering/unregistering has 
jumped significantly between Java 8 and Java 11.

   The following changeset for example (which added an extra listener on the 
Node class) impacted TableView performance significantly:

   commit e21606d3a1b73cd4b44383babc750a4b4721edfd
   Author: Florian Kirmaier 
<f...@sandec.de<mailto:f...@sandec.de><mailto:f...@sandec.de>>
   Date:   Tue Jan 22 09:08:36 2019 -0800

       8216377: Fix memoryleak for initial nodes of Window
       8207837: Indeterminate ProgressBar does not animate if content is added 
after scene is set on window



       Add or remove the windowShowingChangedListener when the scene changes



   I can see that the code for removing listeners in ExpressionHelper.Generic 
is extremely sub optimal and uses a linear search through an array to remove 
listeners.

   I have rewritten this class to use a Set instead of an Array and it has 
fixed our major TableView issues where the performance of the UI seriously 
deteriorated to the point of not being usable. The CPU usage of 
com.sun.javafx.binding.ExpressionHelper.removeListener in the JavaFX 
Application Thread has dropped from 60% to less than 1%.

   I believe this fix will alleviate the major issues of TableViews detailed in 
the above links.
   I have run my fix through the unit test suite and believe it is functionally 
equivalent to the original code, just much faster.

   I am happy to submit a pull request. I am new to openJFX contributing so any 
pointers of what I need to do here would be appreciated.

   Thanks

   Danny



Reply via email to