help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: Changing the Emacs engine to Guile


From: Pascal J. Bourguignon
Subject: Re: Changing the Emacs engine to Guile
Date: Wed, 08 Dec 2010 15:15:15 -0000
User-agent: Gnus/5.101 (Gnus v5.10.10) Emacs/23.2 (gnu/linux)

Cecil Westerhof <Cecil@decebal.nl> writes:

> Op maandag 21 jun 2010 23:04 CEST schreef Pascal J. Bourguignon:
>
>> AFAIK, these two programs don't do the same thing.  Therefore you
>> cannot compare their timings in any meaningful way.
>
> They do the same, the only difference is that the Emacs Lisp version
> uses a buffer and the Guile version uses line by line..


#!/usr/bin/guile \
-e main -s
!#
(use-modules (ice-9 rdelim)
             (ice-9 regex))

(define (main args)
  (let* ((arg-vector       (list->vector args))
         (input-file-name  (vector-ref   arg-vector 1))
         (output-file-name (vector-ref   arg-vector 2))
         (reg-exp          (make-regexp  (vector-ref   arg-vector 3)))
         (substitute-str   (vector-ref   arg-vector 4))

         (end-match        0)
         (found-match      #f)
         (input-file       (open-file input-file-name  "r"))
         (match-length     0)
         (output-file      (open-file output-file-name "w"))
         (start-match      0)
         (this-line        ""))
    (while (not (eof-object? (peek-char input-file)))
           (set! this-line   (read-line input-file))
           (set! found-match (regexp-exec reg-exp this-line))
           (while found-match
                  (set! start-match  (match:start found-match))
                  (set! end-match    (match:end found-match))
                  (set! match-length (- end-match start-match))
                  (while (> match-length (string-length substitute-str))
                         (set! substitute-str (string-append substitute-str 
substitute-str)))
                  (set! found-match  (regexp-exec reg-exp this-line (+ 
end-match 1))))

The above while found-match loop does not modify this-line.
The result is to find the last match on the line.

           (write-line (string-replace this-line
                                       substitute-str
                                       start-match end-match
                                       start-match end-match)
                       output-file))

Therefore this write-line outputs the-line with only the last
occurence of regexp in this-line modified.

Also, (I'm not sure about it I would have to check string-replace, but
my guess is that) the substituted text is (substring substitute-str
start-match end-match), which will be different in the case of emacs
code below.


    (close-port output-file)
    (close-port input-file)))


On the other hand:


    emacs -batch --eval='
      (defun substitute-expression(input-file output-file reg-exp 
substitute-str)
        (let ((match-length))
          (switch-to-buffer (find-file-noselect input-file t t))
          (buffer-disable-undo)
          (while (re-search-forward reg-exp nil t)
            (setq match-length (- (point) (match-beginning 0)))
            (while (> match-length (length substitute-str))
              (setq substitute-str (concat substitute-str substitute-str)))
            (replace-match (substring substitute-str 0 match-length))
          )

this (while (re-search-forward  ...)) loop modifies the line for each
occurence of the regexp, replacing it with (substring substitute-str 0
match-length), which is a different replacement string in general.


          (write-region (point-min) (point-max) output-file)))
    ' --eval='
      (byte-compile '"'"'substitute-expression)
    ' --eval='
      (substitute-expression "'"${inputFile}"'"
                             "'"${outputFile}"'"
                             "'"${regExp}"'"
                             "'"${substituteStr}"'")
    ' 2>/dev/null



>> What's more, you cannot compare apples and oranges, that is, compare
>> generic regular expression code in scheme, and compare highly
>> optimized code to edit a buffer written in C, called from emacs lisp,
>> to compare the two VM for use in emacs.
>>
>> When/if emacs is rewritten to use guile, its buffer editing library
>> written in C will stay the same and be called the same way from scheme
>> than it is from emacs lisp.  This won't impact their performance.
>>
>> So you should rather compare code that doesn't use any library, if you
>> want to compare the emacs VM vs. the guile VM.
>
> Okay, maybe I made a wrong comparison. But the performance of Guile 1.8
> is not good, three other languages that do the same and perform much
> more efficient:

> Especially the Common Lisp version does the same. The AWK and Perl
> version have a optimised input/output. But the Guile version takes 20
> seconds for input/output, so that is only a fraction of the time and not
> the bottleneck.
> The Perl version has the same problem as the Guile version: it does not
> handle multi byte characters.

I don't know about the other implementations, but with clisp you could
also try to use the -C option to have your script compiled before
running it.  On big files it might be worthwhile to spend some time
compiling the script.

But my point here is that in emacs, most code is compiled or byte
compiled, therefore you should compare the speed of the code generated
by sbcl vs. guile.  Benchmarking is hard.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/


reply via email to

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