Andreas Rottmann <a.rottm...@gmx.at> writes: > l...@gnu.org (Ludovic Courtès) writes: > >> Hi Andreas, >> >> I’m all for your suggestion. >> >> Andreas Rottmann <a.rottm...@gmx.at> writes: >> >>> + (define-syntax define-fxop* >>> + (syntax-rules () >>> + ((_ name op) >>> + (define name >>> + (case-lambda >>> + ((x y) >>> + (assert-fixnum x y) >>> + (op x y)) >>> + (args >>> + (assert-fixnums args) >>> + (apply op args))))))) >>> + >>> + (define-fxop* fx=? =) >> >> How about making something like this (untested): >> >> (define-syntax define-fxop* >> (syntax-rules () >> ((_ name op) >> (define-syntax name >> (lambda (s) >> (syntax-case s () >> ((_ x y) >> #'(begin >> (assert-fixnum x y) >> (op x y))) >> ((_ args ...) >> #'(apply op args)) >> (_ #'op))))))) >> >> This way, there’d be no procedure call involved and ‘=’, ‘+’, etc. would >> use the corresponding instruction in the base case. >> > That's an excellent idea, and would probably boost performance quite a > bit. > Sorry to reply to myself, but new evidence has been produced :-).
Using the following macro: (define-syntax define-fxop* (lambda (stx) (define prefix (string->symbol "% ")) (define (make-procedure-name name) (datum->syntax name (symbol-append prefix (syntax->datum name) '-procedure))) (syntax-case stx () ((_ name op) (with-syntax ((proc-name (make-procedure-name #'name))) #'(begin (define (proc-name . args) (assert-fixnums args) (apply op args)) (define-syntax name (lambda (stx) (syntax-case stx () ((_ x-expr y-expr) #'(let ((x x-expr) (y y-expr)) (assert-fixnum x y) (op x y))) ((_ . args) #'(proc-name . args)) (_ (identifier? stx) #'proc-name)))))))))) It turns out that this does not have a great effect on the efficiency; here are the numbers: * stable-2.0 + rotty/wip-fixnum-speed (simple define-fxop*, clever fixnum?) #+begin_example % _build/meta/guile -e main -s benchmark-suite/guile-benchmark --benchmark-suite benchmarks r6rs-arithmetic.bm ;; running guile version 2.0.0.133-e47c9-dirty ;; calibrating the benchmarking framework... ;; framework time per iteration: 1.1444091796875e-7 ("r6rs-arithmetic.bm: fixnum: fixnum? [yes]" 10000000 user 3.42 benchmark 2.2755908203125 bench/interp 2.2755908203125 gc 0.0) ("r6rs-arithmetic.bm: fixnum: fixnum? [no]" 10000000 user 3.42 benchmark 2.2755908203125 bench/interp 2.2755908203125 gc 0.0) ("r6rs-arithmetic.bm: fixnum: fxxor [2]" 10000000 user 6.96 benchmark 5.8155908203125 bench/interp 5.8155908203125 gc 0.0) scheme@(guile-user)> ,time (run-benchmark) clock utime stime cutime cstime gctime 23.81 23.76 0.00 0.00 0.00 0.00 #+end_example * stable-2.0 + rotty/wip-fixnum-speed (macro-based define-fxop*, clever fixnum?) #+begin_example % _build/meta/guile -e main -s benchmark-suite/guile-benchmark --benchmark-suite benchmarks r6rs-arithmetic.bm ;; running guile version 2.0.0.133-e47c9-dirty ;; calibrating the benchmarking framework... ;; framework time per iteration: 1.52587890625e-7 ("r6rs-arithmetic.bm: fixnum: fixnum? [yes]" 10000000 user 3.4 benchmark 1.87412109375 bench/interp 1.87412109375 gc 0.0) ("r6rs-arithmetic.bm: fixnum: fixnum? [no]" 10000000 user 3.42 benchmark 1.89412109375 bench/interp 1.89412109375 gc 0.0) ("r6rs-arithmetic.bm: fixnum: fxxor [2]" 10000000 user 6.72 benchmark 5.19412109375 bench/interp 5.19412109375 gc 0.0) scheme@(guile-user)> ,time (run-benchmark) clock utime stime cutime cstime gctime 22.76 22.73 0.00 0.00 0.00 0.00 #+end_example So, that's around 5% improvment (on the ZIP benchmark) for an IMHO significantly more hackish implementation. I'm not sure that's worth it. WDYT? Regards, Rotty -- Andreas Rottmann -- <http://rotty.yi.org/>