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 on behalf of 
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>>
    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