[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Learning to write interpreted code
From: |
Ludovic Courtès |
Subject: |
Learning to write interpreted code |
Date: |
Thu, 09 Aug 2007 16:49:56 +0200 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) |
Hi,
I've been facing various slowness issues recently, which led me to play
with profilers. Today, I profiled Guile-RPC's XDR encoding routine with
`statprof' and got this:
% cumulative self
time seconds seconds name
9.66 12.64 12.64 not
6.57 9.38 8.59 xdr-basic-type-type-pred
6.53 9.44 8.54 xdr-basic-type-size
5.62 8.26 7.36 xdr-basic-type-encoder
5.11 8.93 6.68 xdr-basic-type?
3.69 4.83 4.83 eq?
[...]
Total time: 130.8 seconds (2147/100 seconds in GC)
Twelve seconds are being spent in `not', 5 seconds in `eq?', and 8
seconds in each record accessor (all of which could be implemented in a
few machine instructions).
So I went ahead and removed the `not' within the loop, rewriting
`(if (not c) a b)' to `(if c b a)', and voilà:
% cumulative self
time seconds seconds name
8.88 1.19 1.08 xdr-basic-type-size
5.14 0.74 0.62 xdr-basic-type-type-pred
4.21 0.68 0.51 xdr-basic-type-encoder
3.74 1.64 0.45 +
3.74 0.45 0.45 eq?
[...]
Total time: 12.11 seconds (167/100 seconds in GC)
An order of magnitude faster! I suppose that, as a side effect, the GC
needed to run less often because the evaluator was producing less
garbage.
Conclusions:
1. When writing code for an interpreter, one has to be prepared for
insignificant things taking surprisingly large amounts of time. :-)
2. My inlining patch [0] was not too irrelevant, I suppose.
3. Upon user request, we may also want to allow the memoizer of `if'
to automatically rewrite expressions of the form `(if (not c) ...)'.
Cheers,
Ludo'.
[0] http://thread.gmane.org/gmane.lisp.guile.devel/6043
- Learning to write interpreted code,
Ludovic Courtès <=