mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
Implement batched updates
No docs yet, more testing needed.
This commit is contained in:
parent
7d82fe353e
commit
ec998ccbc8
6 changed files with 123 additions and 10 deletions
23
src/batch.luau
Normal file
23
src/batch.luau
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
if not game then script = require "test/relative-string" end
|
||||
|
||||
local flags = require(script.Parent.flags)
|
||||
local throw = require(script.Parent.throw)
|
||||
local graph = require(script.Parent.graph)
|
||||
|
||||
local function batch(setter: () -> ())
|
||||
local already_batching = flags.batch
|
||||
|
||||
flags.batch = true
|
||||
|
||||
local ok, err: string? = pcall(setter)
|
||||
|
||||
flags.batch = false
|
||||
|
||||
if not ok then throw(`error occured while batching updates: {err}`) end
|
||||
|
||||
if not already_batching then -- todo: flush anyways?
|
||||
graph.flush_update_queue()
|
||||
end
|
||||
end
|
||||
|
||||
return batch
|
||||
|
|
@ -4,4 +4,4 @@ end
|
|||
|
||||
local is_O2 = inline_test() ~= "inline_test"
|
||||
|
||||
return { strict = not is_O2 }
|
||||
return { strict = not is_O2, batch = false }
|
||||
|
|
|
|||
|
|
@ -193,10 +193,32 @@ local function queue_children<T>(node: StartNode<T>)
|
|||
update_queue.n = i
|
||||
end
|
||||
|
||||
local function flush_update_queue()
|
||||
-- todo: test with recursive batch sets
|
||||
local n0 = 0
|
||||
|
||||
local i = n0 + 1
|
||||
while i <= update_queue.n do
|
||||
local node = update_queue[i]
|
||||
--assert(node.effect)
|
||||
|
||||
if evaluate_node(node) then
|
||||
queue_children(node)
|
||||
end
|
||||
|
||||
update_queue[i] = false :: any
|
||||
i += 1
|
||||
end
|
||||
|
||||
update_queue.n = n0
|
||||
end
|
||||
|
||||
local function update<T>(root: StartNode<T>)
|
||||
local n0 = update_queue.n
|
||||
queue_children(root)
|
||||
|
||||
if flags.batch then return end
|
||||
|
||||
local i = n0 + 1
|
||||
while i <= update_queue.n do
|
||||
local node = update_queue[i]
|
||||
|
|
@ -257,5 +279,6 @@ return table.freeze {
|
|||
create_node = create_node,
|
||||
create_start_node = create_start_node,
|
||||
get_children = get_children,
|
||||
flush_update_queue = flush_update_queue,
|
||||
scopes = scopes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ local create = require(script.create)
|
|||
local apply = require(script.apply)
|
||||
local source = require(script.source)
|
||||
local effect = require(script.effect)
|
||||
local derive = require(script.derive)
|
||||
local cleanup = require(script.cleanup)
|
||||
local untrack = require(script.untrack)
|
||||
local derive = require(script.derive)
|
||||
local batch = require(script.batch)
|
||||
local switch = require(script.switch)
|
||||
local show = require(script.show)
|
||||
local indexes, values = require(script.maps)()
|
||||
|
|
@ -59,6 +60,7 @@ local vide = {
|
|||
-- util
|
||||
cleanup = cleanup,
|
||||
untrack = untrack,
|
||||
batch = batch,
|
||||
read = function<T>(value: T | () -> T): T
|
||||
return if type(value) == "function" then value() else value
|
||||
end,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ local source = vide.source
|
|||
local derive = vide.derive
|
||||
local indexes = vide.indexes
|
||||
local values = vide.values
|
||||
local batch = vide.batch
|
||||
local cleanup = vide.cleanup
|
||||
local create = vide.create
|
||||
|
||||
|
|
@ -132,30 +133,51 @@ ROOT_BENCH("update 1->1->1->1...1000 graph", function()
|
|||
end
|
||||
end)
|
||||
|
||||
-- todo: crashes at 1k
|
||||
-- todo: repeat with batching
|
||||
ROOT_BENCH("update 1000->1 graph", function()
|
||||
-- todo: why does it hang at 1k? it didn't before
|
||||
ROOT_BENCH("update 500->1 graph", function()
|
||||
local srcs = {}
|
||||
for i = 1, 800 do
|
||||
for i = 1, 500 do
|
||||
srcs[i] = source(0)
|
||||
end
|
||||
|
||||
derive(function()
|
||||
for i = 1, 800 do
|
||||
for i = 1, 500 do
|
||||
srcs[i]()
|
||||
end
|
||||
return false
|
||||
end)
|
||||
|
||||
for i = 1, START(1) do
|
||||
for idx = 1, 800 do
|
||||
for idx = 1, 500 do
|
||||
srcs[idx](i)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- todo: optimize, repeat with batching
|
||||
ROOT_BENCH("update 1000x 1->1 common extern. graph", function()
|
||||
ROOT_BENCH("update 1000->1 graph (batched)", function()
|
||||
local srcs = {}
|
||||
for i = 1, 1000 do
|
||||
srcs[i] = source(0)
|
||||
end
|
||||
|
||||
derive(function()
|
||||
for i = 1, 1000 do
|
||||
srcs[i]()
|
||||
end
|
||||
return false
|
||||
end)
|
||||
|
||||
for i = 1, START(1) do
|
||||
batch(function()
|
||||
for idx = 1, 1000 do
|
||||
srcs[idx](i)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
-- todo: optimize this case
|
||||
ROOT_BENCH("update 1000 1->1 common extern. graph", function()
|
||||
local ext = source(-1)
|
||||
|
||||
local srcs = {}
|
||||
|
|
|
|||
|
|
@ -1800,6 +1800,49 @@ TEST("changed()", wrap_root(function()
|
|||
end
|
||||
end))
|
||||
|
||||
TEST("batch()", wrap_root(function()
|
||||
local source = vide.source
|
||||
local derive = vide.derive
|
||||
local batch = vide.batch
|
||||
|
||||
do CASE "child evaluation halted"
|
||||
local a = source(0)
|
||||
|
||||
local count = { b = 0, b2 = 0, c = 0 }
|
||||
|
||||
local b = derive(function()
|
||||
count.b += 1
|
||||
return a() + 1
|
||||
end)
|
||||
|
||||
local b2 = derive(function()
|
||||
count.b2 += 1
|
||||
return a() + 2
|
||||
end)
|
||||
|
||||
local c = derive(function()
|
||||
count.c += 1
|
||||
return b() + b2()
|
||||
end)
|
||||
|
||||
batch(function()
|
||||
a(1)
|
||||
CHECK(count.b == 1)
|
||||
CHECK(count.b2 == 1)
|
||||
CHECK(count.c == 1)
|
||||
end)
|
||||
|
||||
CHECK(count.b == 2)
|
||||
CHECK(count.b2 == 2)
|
||||
CHECK(count.c == 2)
|
||||
|
||||
CHECK(b() == 2)
|
||||
CHECK(c() == 5)
|
||||
end
|
||||
|
||||
-- todo: test batch call in recursive set
|
||||
end))
|
||||
|
||||
TEST("read()", wrap_root(function()
|
||||
local source = vide.source
|
||||
local effect = vide.effect
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue