emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: In support of guile-emacs


From: Alan Mackenzie
Subject: Re: In support of guile-emacs
Date: Tue, 20 Oct 2015 09:53:32 +0000
User-agent: Mutt/1.5.23 (2014-03-12)

Hello, Taylan.

On Mon, Oct 19, 2015 at 11:01:21PM +0200, Taylan Ulrich Bayırlı/Kammer wrote:
> Alan Mackenzie <address@hidden> writes:

> > When I run this in Emacs on my 2.6 GHz Athlong machine, with M-:

> >   (time-it (let ((i 0)) (while (<= i 10000000) (setq i (1+ i)))))

> > , this takes 1.8881s.  (`time-it' is my own macro, not a standard Emacs
> > one.)  So, thus far, it's looking like Guile is a factor of ~700 faster.
> > :-)

> Oh oh, don't forget to byte-compile Elisp.  Was my first mistake too.

Hah!  Yes, I had forgotten to byte-compile it.  Creating a defun for it,
then timing that I get 0.495s.

> >> > ,optimize (let loop ((i 0)) (unless (= 10000000) (loop (+ i 1))))
> >> $2 = (if #f #f)

> >> Oh, heh.  A void 'do' loop doesn't get the same treatment because of
> >> slightly different semantics, but a void named-let loop simply gets
> >> eliminated out.

> > Ah.  Shame.  How about calculating 1 + 2 + 3 + .... + 10,000,000 in a
> > loop, then outputting it?  The sum (50,000,005,000,000) should easily fit
> > into a 64-bit Lisp integer.

> > This:

> >   (time-it (let ((i 0) (s 0)) (while (<= i 10000000) (setq s (+ s i)) (setq 
> > i (1+ i))) (message "%s" s)))

> > takes 3.389s on my machine.

Again, byte-compiled, that takes 0.957s.

> Takes about 0.62s here, when byte-compiled.

Your machine is ~50% faster than mine.

The Guile variant:

> (let ((i 0) (s 0))
>   (while (<= i 10000000)
>     (set! s (+ s i))
>     (set! i (1+ i)))
>   (format #t "~s" s))

> Takes about 0.55s.  That's a very literal transcription of the function
> to Scheme.  A more idiomatic version:

> (let loop ((i 0) (s 0))
>   (if (<= i 10000000)
>       (loop (+ i 1) (+ s i))
>       (format #t "~s" s)))

> Takes about 0.50s.

So, we're talking about a speed up of around 13%/25% on a simple loop
test, depending on whether or not an idiomatic Scheme formulation is
used.  Given that Guile compiled elisp wouldn't be optimised in this way,
it would guess that the 13% is nearer the mark.  But it would take a few
real life tests to measure this better.

> BTW here's a timing function that automatically byte-compiles the
> argument (side-effectfully if a symbol):

> (defun time (function)
>   "Return execution time of calling FUNCTION in seconds as a
> float.  FUNCTION is byte-compiled automatically."
>   (setq function (byte-compile function))
>   (let ((start (current-time)))
>     (funcall function)
>     (let ((end (current-time)))
>       (let ((time (time-subtract end start)))
>         (+ (* (nth 0 time) (expt 2 16))
>            (nth 1 time)
>            (/ (nth 2 time) 1000000.0))))))

Hint: there's a function `float-time' which does the job adequately, and
is easier to manipulate.  For comparison, here's my `time-it' macro
(which doesn't itself do byte compilation):

(defmacro time-it (&rest forms)
  "Time the running of a sequence of forms using `float-time'.
Call like this: \"M-: (time-it (foo ...) (bar ...) ...)\"."
  `(let ((start (float-time)))
    ,@forms
    (- (float-time) start)))

[ .... ]

> > If Guile Emacs is advanced enough, timing the fontification of a file
> > (say, ..../src/xdisp.c in our repository) would be a very meaningful
> > timing.

> I'm guessing that Guile Emacs isn't ready for that yet but, how can one
> time that?

Start by unfontifying the entire file, then scroll through it, fontifying
a screen at a time.  (sit-for 0) is used to ensure fontification at each
stage.  So something like this (untested) would do the job:

(defun fully-fontify ()
  (beginning-of-buffer)
  (font-lock-mode 0)
  (font-lock-mode 1)
  (condition-case nil
    (while t
      (sit-for 0)
      (scroll-up))))

The `condition-case' catches the error thrown when `scroll-up' reaches
the end of the buffer.

> Taylan

-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]