Elpher rendering speed
At the risk of continuing the inanity which has plagued the last few
posts, I've just made an update to Elpher that I feel deserves a post
on its own.
Several people have mentioned (eg [1]) that Elpher can be a bit.. laggy.
Some of this no-doubt has to do with its line-by-line approach to
inserting text into the buffer when displaying gopher directories and
text/gemini documents, which is not easily avoidable. Some of it is
also likely to do with performing regexps over the text to identify
URLs, which I consider a key feature of Elpher and one which I'm
absolutely willing to sacrifice a bit of performance for.
Over the past few weeks however I've started to really notice it.
This is probably because I've been browsing a bit more gemini, and
there tends to be a bit more of a lag there anyway due to the TLS
handshake. Again, likely unavoidable, but it managed to bring the
situation to my attention again and make me start to wonder what the
real problem here was. The situation seemed particularly bad on
link-heavy pages, such as [2]. Hrm.
So finally I fired up the profiler.
Oh yes, did you know - emacs has a built-in profiler for elisp? I
mean, of course it does. But still.
The profiler reports its results as a hierarchy of function calls with
some estimate of the %age of CPU time spent in each. The top level
results seemed in line with my intuition. Yes, it's the document
rendering function (87%). Yes it's the line rendering function within
that (still 87%). Hrm, interesting, it's the button-insertion function
within that (STILL 87%). (Emacs calls clickable text in buffers
"buttons".)
Hold on, what's this though? Within the button-insertion function a
function is called to generate the mouseover help-text, and this is
using 87% of the CPU time. WTF??
Within that function, it turns out a single library function call to
url-encode-url (in order to provide nice normalized URLs in the
mouseover text) is using almost all of the CPU time in rendering this
particular link-heavy page. How embarrassing!!
Of course the first thing I try is just replacing the mousover text
with an empty string. My test page loads in a snap - basically an
order of magnitude improvement. The profiler wasn't lying!
Side note: fixing bugs and squashing performance bottlenecks like
this is absolutely the best part of programming! This is _so much
fun_! :-)
Even though I would have been happy to dispense with mouseover help
text entirely for such a performance boost, it turned out I didn't
have to. It's a common (and awesome) pattern in the Emacs elisp API
for certain variables/properties to accept either a function or a
string. The help-echo text property used by buttons has this feature.
I'd previously been filling each link button with a pre-generated help
text, but what I now do is to just use a reference to a
help-text-generating function instead. Thus the help text is
generated when it's needed rather than when the page is rendered.
(It's currently generated every time it's needed - there's no
caching - but this isn't an issue as you don't need to rapidly read
mouseover texts over and over again.)
SO! As of 2.7.9, rendering speed is significantly improved. The
improvement is so major that there don't even have to be that many
links on the page to notice it. (For instance, my bookmarks page only
contains about 50 links and there used to be a ~0.25s pause every time
I visited it. To good approximation this is completely gone.)
Yay for profiling! (And boo to url-encode-url! Seriously, wow - so slow!)
--
text/plain;charset=utf-8
This content has been proxied by September (ba2dc).