vinum-team / Vinum

A modern reactive state management library for correctness and speed.
MIT License
16 stars 1 forks source link

Memoize Selects and the Revisiting of State Centralization #46

Closed xiyler closed 6 months ago

xiyler commented 6 months ago

It could be worthwhile to conditionally memoize Selects, as this could allow for decreased memory consumption and performance gains in an example like so:

local Store = scope:Source({
    key = 10
})

-- In 0.4, both Select calls return completely new objects, but
-- if memoized Select calls generally, these calls will return the same 
-- object. Increasing performance and decreasing memory usage.
Write(Select(Store, "key"), 20)
print(Read(Select(Store, "key")))

While this is a generally good optimization, we may want to instead rework how Operators deal with state structs that compute/hold luau tables. Should we instead provide utility functions that mutate tables so that you could call a Write call like this:

Write(Store, Mutate({
    key = 40
}) 

This all points to the elephant in the room, which is state centralization. While Selects (and perhaps functions like Mutate) generally make dealing with state centralization easier, they don't just optimize it well.

This is technically tied with how GNRA operates. It prepares the final queue without accounting for whether the actual state object will change its value or not (this can be predicted when given the same input to its dependencies), so we may end up with unnecessary updates when updating Store naively.

xiyler commented 6 months ago

Rejected, since Centrals solve the problem of state centralization/packing better in relation to how the library itself work than Selects do.

Central's RFC: https://github.com/vinum-team/rfc/blob/main/rfcs/utility-central.md