Last active
May 25, 2020 15:51
-
-
Save hiiamboris/4da1bccf63f4506b412977c1673c723c to your computer and use it in GitHub Desktop.
Reactivity benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Red [title: "reactivity benchmark" needs: view] ;) run as `red --cli ...` to eliminate GUI console influence! | |
do https://gitlab.com/hiiamboris/red-mezz-warehouse/-/raw/master/clock.red | |
do-unseen: function [code [block!]] [ | |
old: system/view/auto-sync? | |
system/view/auto-sync?: no | |
do code | |
system/view/auto-sync?: old | |
] | |
extend system/view/VID/styles [ | |
text1: [ | |
template: [type: 'text size: 80x25] | |
init: [ ;) baseline: creates a function, executes, doesn't use it | |
f: func [f _] [ | |
[f/data f/offset f/size] | |
f/text: "text" | |
] | |
f face face | |
] | |
] | |
text2: [ | |
template: [type: 'text size: 80x25] | |
init: [ | |
react/link func [f _] [ | |
[f/data f/offset f/size] ;) define reactive sources (3 sources = 3 reactions) | |
f/text: "text" | |
] [face face] | |
] | |
] | |
] | |
view/no-wait [p: panel []] | |
recycle/off | |
print "=== BASELINE (VIEW ONLY) ===" | |
print "" | |
print "CREATING 1000 FACES x5" | |
loop 5 [clock [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text1]]]] | |
print "SHOWING 1000 FACES" | |
print ["p/pane:" length? p/pane "faces"] | |
clock [show p] | |
clear p/pane | |
clock [recycle] | |
print "" | |
print "=== WITH REACTIVITY ===" | |
print "" | |
print "CREATING 1000 FACES & 3000 REACTIONS x5 (A TOTAL OF 15000 REACTIONS)" | |
loop 5 [clock [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text2]]]] | |
print "SHOWING 1000 FACES & DESTROYING 12000 REACTIONS" | |
print ["p/pane:" length? p/pane "faces"] | |
print ["relations count:" (length? system/reactivity/relations) / 4] | |
clock [show p] | |
print ["relations count:" (length? system/reactivity/relations) / 4] | |
clear p/pane | |
clock [clear-reactions] | |
clock [recycle] | |
unview do-events/no-wait | |
print "" | |
print "=== ONLY REACTIVITY (NO VIEW) ===" | |
print "" | |
print "CREATING 1000 REACTORS x5" | |
b: [[][][][][]] | |
repeat i 5 [clock compose/deep [clear pick b (i) loop 1000 [append pick b (i) reactor [x: 10 y: 2 t: 0 re: copy/deep [self/t: s/s * self/x + self/y]]]]] | |
print "CREATING 15000 REACTIONS" | |
s: reactor [s: 1] | |
repeat i 5 [clock compose [foreach r pick b (i) [react/later r/re]]] | |
print ["relations count:" (length? system/reactivity/relations) / 4] | |
?? b/1/1/t ?? b/2/2/t | |
print "FIRING 15000 REACTIONS" | |
clock [s/s: 2] | |
?? b/1/1/t ?? b/2/2/t | |
print "DESTROYING 15000 REACTIONS" | |
repeat i 5 [clock compose [foreach r pick b (i) [react/unlink r/re 'all]]] | |
print ["relations count:" (length? system/reactivity/relations) / 4] | |
clock [recycle] | |
print "" | |
print "=== ONLY REACTIVITY AND OBJECTS MAINLY UNIQUE ===" | |
print "" | |
print "CREATING 1000 REACTORS x5" | |
b: [[][][][][]] | |
s: reactor [x: 10 y: 2 t: 0 re: [this/t: that/x + that/y + that/t / 10]] | |
repeat i 5 [clock compose/deep [clear pick b (i) loop 1000 [append pick b (i) make s [re: copy/deep re]]]] | |
print "CREATING 15000 REACTIONS" | |
prev: s | |
repeat i 5 [clock compose [foreach r pick b (i) [react/link/later r/re: func [this that] r/re [r prev] prev: r]]] | |
print ["relations count:" (length? system/reactivity/relations) / 4] | |
?? b/1/1/t ?? b/2/2/t | |
print "FIRING 15000 REACTIONS" | |
clock [s/t: 1] | |
?? b/1/1/t ?? b/2/2/t | |
print "DESTROYING 15000 REACTIONS" | |
repeat i 5 [clock compose [foreach r pick b (i) [react/unlink :r/re 'all]]] | |
; print ["relations count:" (length? system/reactivity/relations) / 4] | |
clock [recycle] |
greggirwin
commented
May 24, 2020
With relations: make hash! 1000
and queue: make hash! 100
and fix red/red@5aa78a6:
=== BASELINE (VIEW ONLY) ===
CREATING 1000 FACES x5
232 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text1]]]
230 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text1]]]
230 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text1]]]
228 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text1]]]
230 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text1]]]
SHOWING 1000 FACES
p/pane: 1000 faces
2403 ms [show p]
497 ms [recycle]
=== WITH REACTIVITY ===
CREATING 1000 FACES & 3000 REACTIONS x5 (A TOTAL OF 15000 REACTIONS)
529 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text2]]]
809 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text2]]]
1264 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text2]]]
1219 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text2]]]
2841 ms [do-unseen [clear p/pane loop 1000 [append p/pane make-face 'text2]]]
SHOWING 1000 FACES & DESTROYING 12000 REACTIONS
p/pane: 1000 faces
relations count: 15000
41076 ms [show p]
relations count: 3000
562 ms [recycle]
I added pure reactivity test to the tail of script, without involving View (per @dockimbel's advice).
Now I'm getting with blocks:
=== ONLY REACTIVITY (NO VIEW) ===
CREATING 1000 REACTORS x5
44.0 ms [clear pick b 1 loop 1000 [append pick b 1 reactor [x: 10 y: 2 t: 0 re
46.0 ms [clear pick b 2 loop 1000 [append pick b 2 reactor [x: 10 y: 2 t: 0 re
45.0 ms [clear pick b 3 loop 1000 [append pick b 3 reactor [x: 10 y: 2 t: 0 re
43.0 ms [clear pick b 4 loop 1000 [append pick b 4 reactor [x: 10 y: 2 t: 0 re
46.0 ms [clear pick b 5 loop 1000 [append pick b 5 reactor [x: 10 y: 2 t: 0 re
CREATING 15000 REACTIONS
229 ms [foreach r pick b 1 [react/later r/re]]
586 ms [foreach r pick b 2 [react/later r/re]]
930 ms [foreach r pick b 3 [react/later r/re]]
1282 ms [foreach r pick b 4 [react/later r/re]]
1616 ms [foreach r pick b 5 [react/later r/re]]
relations count: 15000
b/1/1/t: 0
b/2/2/t: 0
FIRING 15000 REACTIONS
1834 ms [s/s: 2]
b/1/1/t: 22
b/2/2/t: 22
DESTROYING 15000 REACTIONS
2246 ms [foreach r pick b 1 [react/unlink r/re 'all]]
1741 ms [foreach r pick b 2 [react/unlink r/re 'all]]
1246 ms [foreach r pick b 3 [react/unlink r/re 'all]]
750 ms [foreach r pick b 4 [react/unlink r/re 'all]]
252 ms [foreach r pick b 5 [react/unlink r/re 'all]]
relations count: 0
34.0 ms [recycle]
And with hashes (with #4466 fixed):
=== ONLY REACTIVITY (NO VIEW) ===
CREATING 1000 REACTORS x5
45.0 ms [clear pick b 1 loop 1000 [append pick b 1 reactor [x: 10 y: 2 t: 0 re
43.0 ms [clear pick b 2 loop 1000 [append pick b 2 reactor [x: 10 y: 2 t: 0 re
44.0 ms [clear pick b 3 loop 1000 [append pick b 3 reactor [x: 10 y: 2 t: 0 re
45.0 ms [clear pick b 4 loop 1000 [append pick b 4 reactor [x: 10 y: 2 t: 0 re
52.0 ms [clear pick b 5 loop 1000 [append pick b 5 reactor [x: 10 y: 2 t: 0 re
CREATING 15000 REACTIONS
500 ms [foreach r pick b 1 [react/later r/re]]
1464 ms [foreach r pick b 2 [react/later r/re]]
3099 ms [foreach r pick b 3 [react/later r/re]]
3060 ms [foreach r pick b 4 [react/later r/re]]
8417 ms [foreach r pick b 5 [react/later r/re]]
relations count: 15000
b/1/1/t: 0
b/2/2/t: 0
FIRING 15000 REACTIONS
1567 ms [s/s: 2]
b/1/1/t: 22
b/2/2/t: 22
DESTROYING 15000 REACTIONS
3044 ms [foreach r pick b 1 [react/unlink r/re 'all]]
2379 ms [foreach r pick b 2 [react/unlink r/re 'all]]
1702 ms [foreach r pick b 3 [react/unlink r/re 'all]]
1014 ms [foreach r pick b 4 [react/unlink r/re 'all]]
341 ms [foreach r pick b 5 [react/unlink r/re 'all]]
relations count: 0
34.0 ms [recycle]
Looks like hash is up to 5 times slower ;) And also non-linear in it's complexity growth (depends on the bucket size??).
stop-reactor
is linear though (used by View only), needs a fix. But other linear or worse timings are curious, not obvious right away. red/red#3536 ?
I'm getting better timings when all objects are mostly unique in relations
(added test 4 to the script):
=== ONLY REACTIVITY AND OBJECTS MAINLY UNIQUE ===
CREATING 1000 REACTORS x5
35.0 ms [clear pick b 1 loop 1000 [append pick b 1 make s [re: copy/deep re]]]
33.0 ms [clear pick b 2 loop 1000 [append pick b 2 make s [re: copy/deep re]]]
33.0 ms [clear pick b 3 loop 1000 [append pick b 3 make s [re: copy/deep re]]]
32.0 ms [clear pick b 4 loop 1000 [append pick b 4 make s [re: copy/deep re]]]
38.0 ms [clear pick b 5 loop 1000 [append pick b 5 make s [re: copy/deep re]]]
CREATING 15000 REACTIONS
184 ms [foreach r pick b 1 [react/link/later r/re: func [this that] r/re [r p
452 ms [foreach r pick b 2 [react/link/later r/re: func [this that] r/re [r p
912 ms [foreach r pick b 3 [react/link/later r/re: func [this that] r/re [r p
852 ms [foreach r pick b 4 [react/link/later r/re: func [this that] r/re [r p
2446 ms [foreach r pick b 5 [react/link/later r/re: func [this that] r/re [r p
relations count: 15000
b/1/1/t: 0
b/2/2/t: 0
FIRING 15000 REACTIONS
552 ms [s/t: 1]
b/1/1/t: 1
b/2/2/t: 1
DESTROYING 15000 REACTIONS
922 ms [foreach r pick b 1 [react/unlink :r/re 'all]]
719 ms [foreach r pick b 2 [react/unlink :r/re 'all]]
515 ms [foreach r pick b 3 [react/unlink :r/re 'all]]
313 ms [foreach r pick b 4 [react/unlink :r/re 'all]]
112 ms [foreach r pick b 5 [react/unlink :r/re 'all]]
root: 4720/6799, runs: 0, mem: 49425200
(nevermind the GC caused crash)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment