all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Re: Changing the Emacs engine to Guile
       [not found] ` <87iq5cmjgp.fsf@fh-trier.de>
@ 2010-06-21 16:40   ` Andreas Politz
       [not found]   ` <87y6e81d6f.fsf@linux-lqcw.site>
  1 sibling, 0 replies; 7+ messages in thread
From: Andreas Politz @ 2010-06-21 16:40 UTC (permalink / raw)
  To: help-gnu-emacs

Andreas Politz <politza@fh-trier.de> writes:

>
> If you want to read about it, you might want to start here:
>
> http://www.emacswiki.org/emacs/GuileEmacs
>

Oops, it's not there it's here :

http://lists.gnu.org/archive/html/emacs-devel/2010-04/msg00507.html
http://lists.gnu.org/archive/html/emacs-devel/2010-04/msg00665.html

-ap


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Changing the Emacs engine to Guile
       [not found] <87fx0g2yu6.fsf@linux-lqcw.site>
       [not found] ` <87iq5cmjgp.fsf@fh-trier.de>
@ 2010-06-21 19:22 ` Cecil Westerhof
  1 sibling, 0 replies; 7+ messages in thread
From: Cecil Westerhof @ 2010-06-21 19:22 UTC (permalink / raw)
  To: help-gnu-emacs

Op maandag 21 jun 2010 17:24 CEST schreef Cecil Westerhof:

> I read somewhere (I think this list) that there is the idea to change
> the engine from Emacs to Guile. I am afraid that this could result in a
> very big performance hit. A little script I wrote in Emacs Lisp takes 43
> seconds. When implemented in Guile it takes 102 seconds. So almost 2½
> times as long. So I was wondering: why do they want to change the Emacs
> engine?

Some other metrics:
    Common Lisp 45 seconds
    Perl        27 seconds (with a Perl optimisation)
    AWK         29 seconds
    sed        260 seconds

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Changing the Emacs engine to Guile
       [not found]   ` <87y6e81d6f.fsf@linux-lqcw.site>
@ 2010-06-21 21:04     ` Pascal J. Bourguignon
       [not found]       ` <878w671qvm.fsf@linux-lqcw.site>
  0 siblings, 1 reply; 7+ messages in thread
From: Pascal J. Bourguignon @ 2010-06-21 21:04 UTC (permalink / raw)
  To: help-gnu-emacs

Cecil Westerhof <Cecil@decebal.nl> writes:

> Op maandag 21 jun 2010 18:36 CEST schreef Andreas Politz:
>
>> very big performance hit. I did absolutely nothing to support this
>> assumption, which shows that Guile is 2½ times slower. So I was
>
> Attached the Guile script.
>
>
> #!/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))))
>            (write-line (string-replace this-line
>                                        substitute-str
>                                        start-match end-match
>                                        start-match end-match)
>                        output-file))
>     (close-port output-file)
>     (close-port input-file)))
>
>
> My Emacs Lisp script:
>     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))
>           )
>           (write-region (point-min) (point-max) output-file)))
>     ' --eval='
>       (byte-compile '"'"'substitute-expression)
>     ' --eval='
>       (substitute-expression "'"${inputFile}"'"
>                              "'"${outputFile}"'"
>                              "'"${regExp}"'"
>                              "'"${substituteStr}"'")
>     ' 2>/dev/null

AFAIK, these two programs don't do the same thing.  Therefore you
cannot compare their timings in any meaningful way.


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.


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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Changing the Emacs engine to Guile
       [not found]       ` <878w671qvm.fsf@linux-lqcw.site>
@ 2010-06-22  8:38         ` Pascal J. Bourguignon
  2010-06-22 10:05           ` Cecil Westerhof
  0 siblings, 1 reply; 7+ messages in thread
From: Pascal J. Bourguignon @ 2010-06-22  8:38 UTC (permalink / raw)
  To: help-gnu-emacs

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/


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Changing the Emacs engine to Guile
  2010-06-22  8:38         ` Pascal J. Bourguignon
@ 2010-06-22 10:05           ` Cecil Westerhof
  2010-06-22 17:28             ` Pascal J. Bourguignon
  0 siblings, 1 reply; 7+ messages in thread
From: Cecil Westerhof @ 2010-06-22 10:05 UTC (permalink / raw)
  To: help-gnu-emacs

Op dinsdag 22 jun 2010 10:38 CEST schreef Pascal J. Bourguignon:

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

I just hacked it fast to try it out. I only checked the standard case
where I changed the spaces at the beginning of the line with non break
spaces. I just tried something else and found this behaviour. As they
say: haste makes waste. There is also another bug, with certain input I
can get a value out of range. Next time I should verify my code and not
publish it immediately. :-{


> 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.

I did a diff of the files generated by Guile and Emacs Lisp (when using
single byte characters) and they where the same. This was the case where
only the spaces at the beginning of the line where replaced.

I need to make a more robust version and make some test cases and test
again.

> 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.

Why? I would think the replacement string is the same. (When using
single 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.

In my script I have:
    exec clisp -C "$0" "$@" 

That is not correct?


> 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.

As I understood it Guile compiles before executing. That is not correct?

Well, if the big time difference is nothing to worry about, I'll keep
still. ;-}

For the moment being I still prefer Emacs Lisp for scripting above
Guile. ;-]

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Changing the Emacs engine to Guile
  2010-06-22 10:05           ` Cecil Westerhof
@ 2010-06-22 17:28             ` Pascal J. Bourguignon
  2010-06-22 20:40               ` Cecil Westerhof
  0 siblings, 1 reply; 7+ messages in thread
From: Pascal J. Bourguignon @ 2010-06-22 17:28 UTC (permalink / raw)
  To: help-gnu-emacs

Cecil Westerhof <Cecil@decebal.nl> writes:

>> 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.
>
> Why? I would think the replacement string is the same. (When using
> single byte characters.)

With:

substitute-str = "Abcdef" ; initally
start-match    =  4
end-match      = 12
match-length   =  8


substitute-str will become "AbcdefAbcdef",
and   (substring substitute-str 0 match-length)        = "AbcdefAb"
while (substring substitute-str start-match end-match) = "efAbcdef"


>> 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.
>
> In my script I have:
>     exec clisp -C "$0" "$@" 
>
> That is not correct?

Oh yes. Sorry I overlooked that -C.  
So the script is compiled and it should run fast on big input.



>> 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.
>
> As I understood it Guile compiles before executing. That is not correct?
>
> Well, if the big time difference is nothing to worry about, I'll keep
> still. ;-}
>
> For the moment being I still prefer Emacs Lisp for scripting above
> Guile. ;-]
>
> -- 
> Cecil Westerhof
> Senior Software Engineer
> LinkedIn: http://www.linkedin.com/in/cecilwesterhof

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Changing the Emacs engine to Guile
  2010-06-22 17:28             ` Pascal J. Bourguignon
@ 2010-06-22 20:40               ` Cecil Westerhof
  0 siblings, 0 replies; 7+ messages in thread
From: Cecil Westerhof @ 2010-06-22 20:40 UTC (permalink / raw)
  To: help-gnu-emacs

Op dinsdag 22 jun 2010 19:28 CEST schreef Pascal J. Bourguignon:

>>> 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.
>>
>> Why? I would think the replacement string is the same. (When using
>> single byte characters.)
>
> With:
>
> substitute-str = "Abcdef" ; initally
> start-match    =  4
> end-match      = 12
> match-length   =  8
>
>
> substitute-str will become "AbcdefAbcdef",
> and   (substring substitute-str 0 match-length)        = "AbcdefAb"
> while (substring substitute-str start-match end-match) = "efAbcdef"

I made a stupid mistake. It did not show because I only changed a
substring at the start of the line. Better code is at:
    http://www.decebal.nl/guile/sources/substituteExpression.scm

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-06-22 20:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <87fx0g2yu6.fsf@linux-lqcw.site>
     [not found] ` <87iq5cmjgp.fsf@fh-trier.de>
2010-06-21 16:40   ` Changing the Emacs engine to Guile Andreas Politz
     [not found]   ` <87y6e81d6f.fsf@linux-lqcw.site>
2010-06-21 21:04     ` Pascal J. Bourguignon
     [not found]       ` <878w671qvm.fsf@linux-lqcw.site>
2010-06-22  8:38         ` Pascal J. Bourguignon
2010-06-22 10:05           ` Cecil Westerhof
2010-06-22 17:28             ` Pascal J. Bourguignon
2010-06-22 20:40               ` Cecil Westerhof
2010-06-21 19:22 ` Cecil Westerhof

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.