[External] : Re: Experiment: Node properties
John Hendrikx
john.hendrikx at gmail.com
Tue Feb 24 23:18:36 UTC 2026
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 <john.hendrikx at gmail.com>
> *Date: *Monday, February 23, 2026 at 23:05
> *To: *Andy Goryachev <andy.goryachev at oracle.com>,
> openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
> *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 <openjfx-dev-retn at openjdk.org> on behalf of
> John Hendrikx <john.hendrikx at gmail.com>
> *Date: *Thursday, February 19, 2026 at 15:28
> *To: *openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
> *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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20260225/340f1ed2/attachment-0001.htm>
More information about the openjfx-dev
mailing list