Display Scheme Performance Issues
From Electron Cloud
Initial results with dragging a button widget around are not good. I measured the latency like this:
(input-loop (lambda (e) (let ([timestamp (current-time)]) (set! event-latencies (cons (- (time->nanoseconds timestamp) (* 1000000000 (-> e 'time))) event-latencies)))
which should get the number of nanoseconds between the time the tslib event occurred (in C code) to the time the event object was received in the event loop, and accumulate those latencies in a list. Then I print out the list every 100 events, and reset it. As I drag the button around, the latencies are all over, going from less than 1/10 second to 3 seconds.
- The garbage piles up - every event is a new object and they have to be collected some time
- It takes more time to draw the button at its new position, than the time before another event comes in. The events get backed up in the TCP socket.
But I see that the painting is "bursty" - the rate of new buttons being painted is not smooth.
- Implement a ring buffer in dsinp.scm for all events; then they never need to be created, only banged into a vector of vectors or some such. The trouble is that it's hard to use one vector for every kind of event, and no objects are allowed.
- Use a different ring buffer for each event type. When polling the "event queue" (which is now virtual - not just one queue) check to see which buffer has the oldest event, and that's the next one to process.
- Allow TCP to be the buffer - just keep processing the events one at a time, but bang values into the existing object rather than creating a new one each time. The contract is that the recipient of an event must either process it completely right away, or make a copy if he wants to keep it around.
- If painting is taking too long, try to skip some events in the case that we are just dragging an object.
- Need to create dsinp-local.scm anyway - it will be directly linked to tslib and will not use a socket. But I'm thinking most of the latency is somewhere else, not in TCP.
- dsinp.scm bangs values into an existing event rather than making a new one: maybe better, but I can see something else is a bigger deal than the garbage (probably painting)
- filter drag events if the state is the same (still pressed, was pressed before, same widget): seems to have helped some more but it's still not fast enough, can still get latencies in the 6-second range if I drag long enough...
- OK it's TCP after all... I wrote dsinp-local.scm and worst-case latency is about 0.03 seconds.