egallesio / STklos

STklos Scheme
http://stklos.net
GNU General Public License v2.0
67 stars 17 forks source link

Optimize `in-module` for `SCHEME` #636

Closed jpellegrini closed 6 days ago

jpellegrini commented 1 month ago

(in-module mod symb . default) will now use %%in-scheme when mod is SCHEME.

(macro-expand '(in-module SCHEME list))

=> (apply symbol-value* 'list (find-module 'SCHEME) '())

stklos> (disassemble-expr '(in-module SCHEME list))

000:  PREPARE-CALL
001:  GLOBAL-REF-PUSH      0
003:  CONSTANT-PUSH        1
005:  PREPARE-CALL
006:  CONSTANT-PUSH        2
008:  GREF-INVOKE          3 1
011:  PUSH
012:  NIL-PUSH
013:  GREF-INVOKE          4 4
016:

The new code:

(macro-expand '(in-module SCHEME list))

=> (%%in-scheme 'list)

stklos> (disassemble-expr '(in-module SCHEME list))

000:  CONSTANT             0
002:  INSCHEME
003:

Following is an illustration of the speedup.

(time
  (let ((a #f))
    (repeat 10_000_000
      (set! a (in-module SCHEME list))) a))

Old code: around 1200 ms New code: around 300 ms

However, this optimization is only done when there is no default passed to in-module, because using with-handler around %%in-scheme resulted in a huge slowdown.

If there is a way to call %%in-scheme and trap its result without using with-handler, maybe it could be added later.

egallesio commented 6 days ago

Nice. Merged.