DrRacket, now more responsive

The Racket Blog 2013-03-15

DrRacket is now more responsive when editingthan the 5.3.1 release. How much more?Well, I ran a script that starts up DrRacket,opens class-internal.rkt from the distributionand puts the insertion point right before the first" character. It then repeats these three steps 10 times:first it types fdjafjdklafjkdalsfjdaklfjdkaslfdjafjdklafjkdalsfjdaklfjdkaslas fast as it can, then it types the same number of backspaces. Next it type "a andwaits for the syntax colorer to finish adjusting the colors. Then it deletesthose two (again with two backspaces) finally waits for background check syntax to complete. The script also measures the number of wall-clock milliseconds that the handlingof each event took and here are the results: image Each vertical bar’s hight is proportional to the percentage of the eventsthat took at least the corresponding number of milliseconds. The red barsshow how well version 5.3.1’s DrRacket does, and the blue shows how thecurrent git head fares (as of http://git.racket-lang.org/plt/commit/a4d440a5). As you can see, about 80% of the events took less than 26 milliseconds to completein the current version, but more like 60 milliseconds in 5.3.1. As some senseof scale, a television refreshes its screen every 16 2/3s millseconds, so ifall of the events took less than that then DrRacket would feel veryresponsive indeed.

How?

The key to finding all of the performance improvements wasfinding something to measure. It sounds simple (and indeed,it didn’t take long to do), butonce I had that, it because relatively easy to find suspiciouslyslow events, to sort out what they were doing and to speedthem up. (Thanks toMatthewfor this excellent advice!) Specifically, I added a bunch of logging to variousparts of racket/gui, framework,and DrRacket itself. For example, the graphs above are generated from logginginformation about how long events take to be handled. Some of the problems were stupid things, e.g.,there was one placewhere DrRacket was overriding a callback that happened on each keystrokethat would invalidate the entire visible region of the editor. Thisforced the entire buffer to be redrawn on each keystroke, makingDrRacket’s sluggishness proportional to the size of the definitionswindow(!). The performance graph above was recorded a smallish window, namely maximzedon my laptop: 1365x740. A bigger window doesn’t change the blue bars, but here’show a 1102x1174 changes the red ones:  image There were two more complex fixes. First: background check syntax.It runs mostly in a separate, parallel place and thus(on a multi-core machine) doesn’t interfere with DrRacket’s editing all. The last phase,however, is to communicate the results of check syntax back and that hasto update state on the GUI and thus competes with the handling of callbacks.This communication breaks up the check syntax information into chunksand installs that information one chunk at a time, so as to avoidtying up the event handling thread for too long.Thanks to some logging, I found that some of the chunks were too largeand was able to split them up into smaller chunks. The most complex change was in the syntax colorer. It used to use a co-routinethat would parse part of the buffer, suspend the co-routine, color the part it parsed,and then yield control back to handle other events.Unfortunately, the coroutine wouldcommonly run for 10 or 15 milliseconds, but then build up 30 or 40 milliseconds worthof work to do to color the buffer. The fix to the colorer was to eliminate the co-routineand interleave the coloring and the parsing, meaning the whole process now hasfiner granularity, and thus is able to be interrupted more frequently andmore accurately.

Not done yet

There is still a lot more to do. Editing scribble filesis less responsive and the contour window definitely still makesDrRacket sluggish. Yesterday I was able to get DrRacketin a state that brought back some sluggishness and I don’t know howI did that (restarting DrRacket got rid of the problem, unfortunately).I also think I need to look more closely and what happens whenpurple search bubbles are visible. An interactive GC would probablyalso help. If you spot some way to make DrRacket feel more sluggish than it should be,please let me know!