Closed kasbah closed 10 years ago
This binary fractal tree for instance will use 100% CPU on one core constantly (core2duo 1.8Ghz), even when you don't move the mouse or resize the window: https://gist.github.com/kasbah/b6e638655f18c1e11a2c It even does it when using constant signals: https://gist.github.com/kasbah/d0170cd0d4807d18f2a6
Yeah, constant signals will simply be sampled the same as a generated signal, so that definitely won't work.
Like I suggested in the thread, I think a cheap but strong optimisation is to hash the AST and window state and only render if it has changed. I'll investigate whether there's any other algorithms I could apply here too. The most obvious speedup is to nuke the GTK stack and use OpenGL but that's still a long way away.
An interesting idea might be to use FRP.Elerea.Param
rather than FRP.Elerea.Simple
. Briefly reading the documentation, I think this would allow you to write elements that changed to an IORef or something (which you pass as a parameter), which you could then check before you render.
Bonus points for also writing the bounds of the changed areas and performing partial renders.
I started hacking on this a bit over on my fork. I have lift working with the example but I am stuck on ~~
i.e. <*>
i.e. liftN
.
Posted a question over on SO.
I did look at FRP.Elerea.Param
as well but didn't fully grasp how to make use of it.
Any pointers, comments or questions are appreciated.
OK, so the problem is solved thanks to Reite. With this new definition of Signal
all the types to lift
and constant
etc line up with their Elm counterparts.
With Signal
being an instance of Applicative
<~
becomes a synonym of <$>
and ~~
of <*>
. It seems almost wasteful to define these.
I believe Elerea.Clocked
could help with setting the sampling rate more accurately (right now I have a threadDelay only when no updating is necessary--which would mean things like random
would drive the network at a stupid speed).
Looking over Elerea.Param
again it seems it might be good for passing the engine to the signalgens so that the user doesn't have to pass it. Writing things like Mouse.position engine
seemed weird when I came to Helm from Elm.
I was playing around a little with writing a Gtk back-end and if we want to support different back-ends (set by an engine-config paramerter) then you really need the engine info at all signalgens so they know what to do based on whether it is a Gtk or an SDL window.
Another interesting idea here is supporting partial renders based on the signals or even "layers" cached on surfaces bound to signal diffs.
Opened #70 for this. Not sure why Github didn't figure that out.
Agreed about getting rid of the Mouse.position engine
- it was just an ugly workaround. Didn't realise that the param engine would allow it to work without being passed an engine.
I am not sure it does. It was just a thought. I will look into it after I am finished with the new push-based signalling.
Yeah well we certainly need to work it out in order to do custom engine backends.
Helm does not need to re-render when inputs haven't changed.
See discussion here:https://groups.google.com/forum/#!topic/helm-dev/xZCffo1yboU