Hi Andy, I'm currently not having a lot of spare time to do active FX (application) development, so unfortunately I probably won't get around to playing with this any time soon (I usually do most of my FX work when unemployed or when I'm on holidays :)). However, I'll follow the results with interest. The topic of fast data structures and more efficient use of cpu/memory is always fascinating.
Anyway, thanks for hearing me out, perhaps it was useful. --John On 24/02/2026 18:03, Andy Goryachev wrote: > All good points. The reason I asked the community for the feedback is > to get more data with real applications. > > Would you like to try it with /your /application? Would you share the > results? > > Thanks > -andy > > > > *From: *John Hendrikx <[email protected]> > *Date: *Monday, February 23, 2026 at 23:05 > *To: *Andy Goryachev <[email protected]>, > [email protected] <[email protected]> > *Subject: *[External] : Re: Experiment: Node properties > > This Message Is From an External Sender > This message came from outside your organization. > Report Suspicious > <https://us-phishalarm-ewt.proofpoint.com/EWT/v1/ACWV5N9M2RV99hQ!NB2w9kOkmgLOPxPqHXmUmLdxC9ZtwG8cWgWC3QrerJBijvilB58UVSfh4k_zegB5C4cYQuZsUgja4MdmMuDGNKl1z77lAqJtu1aEvg$> > > > Thanks for the taking the time to respond. > > On 24/02/2026 00:32, Andy Goryachev wrote: > > > What trade off are you making here? It seems we're trading a > small memory gain for more CPU use (extra indirection, walking a > list linearly to find the correct property on each use/access VS > no indirection, no list walking). > > > You are right. The tradeoff is non-zero memory gain (a few > megabytes, to the tune of maybe 5% of total heap size) at the cost > of extra CPU cycles. The rationale is that even though we consume > extra CPU, it's much less noticeable because of the cache-friendly > implementation and non-zero positive impact on garbage collector > (less memory to scan). > > What is more cache friendly about adding several extra indirections to > get to a property's value? Let me see: > > Before: > > - isFocusTraversable(): get property -> get value > > After: > > - isFocusTraversable(): get fast map -> get key ArrayList -> get > internal array -> get value ArrayList -> get internal array -> get > property -> get value > > For the garbage collector, the properties are likely going to be in an > area of the GC collector that will be scanned rarely, and not part of > the frequent scans for young objects. I don't think we can generally > conclude that having less memory used will have an overall positive > impact on the GC here. The properties will be seen as long-lived by > the GC, and will reside in an area only scanned rarely, which has very > little impact on the performance of most GC implementations. > > > > > Are the resource constrained platforms you named generally memory > or CPU constrained? > > > I asked Gluon for some feedback on iOS/Android. However, my > previous experience with a large trading application says that > memory footprint savings outweighs the CPU cycles, so I would > imagine we'll get a net gain even on the desktop. > > That's anecdotal, and will depend on the type of application, > platform, CPU cores available, etc. So while you may be correct for > your trading application, it may be completely the opposite for a task > tracking application. In general, memory use is hardly a factor for > most applications; most Java apps don't even bother to limit the heap, > yet complain about several GB's of memory use when they have a > retained size of less than half a GB. Not that I'm not in favor of > reducing memory footprint, but I seriously wonder if there is much to > gain at the property level. > > > > > > Have you investigated a breakdown of JavaFX memory use, and did > the amount of memory used by properties come out on top here? > > > There is some statistics provided in > > https://github.com/andy-goryachev-oracle/Test/blob/main/doc/Experiments/NodeProperties.md > , > please take a look. > > I took a look, but could only find statistics about properties. I > didn't see a breakdown of general JavaFX memory use (the other 95%) to > see if properties are the lowest hanging fruit. > > > > > Would the gains you made here become irrelevant or less relevant > with Compact Object Headers [https://openjdk.org/jeps/519] > > > Compact Object Headers are almost irrelevant here - the stats that > were collected count the number of pointers saved (assumed 8 bytes > per pointer on 64 bit). The stats ignore any other possible savings. > > Compact Object Headers is especially relevant here as you're > optimizing small objects (properties) on which JEP519 offers the most > relative gain. Enabling it may reduce the 5% memory gain you measured > to a smaller margin, which impacts the rationale for this change. > > Furthermore, if we're talking about saving memory, I think we can > assume we're using small heaps (less than 32 GB). In that case, > Hotspot will use 4 bytes per pointer (compressed OOPs) not 8, so your > assumption of 8 bytes per pointer will be incorrect in the vast > majority of JavaFX cases. > > > > > I think the property look-up system cannot reasonably be List > (FastMap despite its name is a List). Converting this to a map > however is likely to require a small object (like Map.Entry) which > will further reduce any gains you made here I think. > > > The FastMap is a map-like (key-value) storage, even though it's > implemented as an array. There is a debate as to what would the > most efficient implementation entail (a hashmap, one array, or two > arrays like the POC currently uses). The idea is not to put > *all* the properties into the container, but only the rarely used > ones, with the end result of having a few (less than 4-6, say). > This makes the object small and cache-friendly, which further > speeds up the access. > > I'm aware of the intentions to only put the rarely used properties > there. What is rarely used will depend on the application. How many > properties will end up being stored there also depends on the > application. What if the app does need several of these properties > and this structure grows to contain 20-30 properties? > > Currently your proposal wants to store these rarely used properties in > an O(n) structure, whereas a hash based solutions are O(1), and where > doing nothing is even faster as there is no map at all. > > So although your map implementation may be small and cache friendly > (that last point being debatable, see indirection count), it degrades > badly when there are more than the predicted amount of properties, and > requires many more indirections than the base case of doing nothing. > > There is talk about not having to do an expensive `hashCode` call in > your proposal. First, `hashCode` is really cheap for objects not > implementing equality as it falls back on the Object#hashCode. I > believe this is the case for properties. Even if it isn't the case, > you could use the identity hash code here (the `==` equivalent in the > hashing world). > > However that "expensive" call is what enables the O(1) lookup of the > value you are interested in, which can be truly cache friendly with > the right structure (array based open addressed map). > > --John > > > > Thanks! > > -andy > > > > > *From: *openjfx-dev <[email protected]> on behalf of > John Hendrikx <[email protected]> > *Date: *Thursday, February 19, 2026 at 15:28 > *To: *[email protected] <[email protected]> > *Subject: *Re: Experiment: Node properties > > > On 04/02/2026 22:17, Andy Goryachev wrote: > > I would like to share the results of a little experiment > involving optimization of storage of Node properties. The > basic idea is to create a compact fast map-like container to > hold the rarely instantiated properties in order to reduce the > application memory footprint. > > The savings are not overwhelming, but not exactly zero. I > would imagine this optimization might be more interesting in > any resource constrained environment such as Android / iOS / > RaspberryPi. Please refer to [0] for the details. > > What trade off are you making here? It seems we're trading a > small memory gain for more CPU use (extra indirection, walking a > list linearly to find the correct property on each use/access VS > no indirection, no list walking). > > Are the resource constrained platforms you named generally memory > or CPU constrained? > > Have you investigated a breakdown of JavaFX memory use, and did > the amount of memory used by properties come out on top here? > > Would the gains you made here become irrelevant or less relevant > with Compact Object Headers [https://openjdk.org/jeps/519] > > > > I encourage you to try it with your application, to see > whether you notice any change in memory consumption and/or > performance. Let me know what you think! > > I like the idea, but I wonder if there really is much to gain > here, and whether those gains will hold up with future Java > improvements. > > I think the property look-up system cannot reasonably be List > (FastMap despite its name is a List). Converting this to a map > however is likely to require a small object (like Map.Entry) which > will further reduce any gains you made here I think. > > --John > > > Cheers, > -andy > > > *References* > > [0] > > https://github.com/andy-goryachev-oracle/Test/blob/main/doc/Experiments/NodeProperties.md >
