Skip to content

[th/optimize-weak-ref-list] rework GObject's `WeakRefData` to track references in an array instead of GSList

Thomas Haller requested to merge th/optimize-weak-ref-list into main

I think it's worth optimizing the core of GObject, for efficiency and memory consumption.

Using a GSList is quite convenient (in particular in terms of writing concise code), but not as efficient as could be.

Replace it by a list of pointers. And the first weak ref is interned/embedded in WeakRefData itself.

I did some (naive) measurements, and it's measurably faster. However, to be fair, it's only faster by a few percent(*). What is also interesting, is that it requires less heap allocations.

(*) the unrealistic /object/weak-ref/many unit tests (with -m slow) gets 80% faster.

For example

  • with len==1 it requires no additional allocation and saves one GSList.
  • with len>1 we allocate a buffer, by doubling the array. For example, with 2 elements, we allocate an array of 4. This is the worst case, where we allocate 4 pointers to track two element. Note that 2 GSList also require 2 x 2 pointers (albeit two separate heap allocations, which may or may not have additional overhead).

The buffer doesn't shrink, until it reaches a length of 1. In that sense, the GSList approach is better to shrink the memory. Not shrinking is an intentional choice, in the hope that we might still reuse the memory later. If we think it would be better, we could easily shrink the buffer (to not do worse than GSList in this regard). The buffer now also shrinks (when 75% empty to 50%). That means, in the worst case we waste 75% of the array (while with GSList we always require +50% for the next pointer).

Edited by Thomas Haller

Merge request reports