[plt-scheme] Performance inconsistency of call-with-values
I like LAMBDA of PLT because of its inherent diverse functions & speed.
CALL-WITH-VALUES seems to show performance inconsistency according to
the different forms of each argument that do the same function. (A year
ago, I reported the problem in relation to its first argument to PLT.)
;;; adbmal-test-mz.scm
;;#lang scheme/base
(module adbmal mzscheme
(require (lib "include.ss"))
(provide test-v1 test-w1 test-p1 test-q1 test-m1 test-n1
test-v2 test-w2 test-p2 test-q2 test-m2 test-n2
dotimes adbmal mu nu)
(include "adbmal-test.scm"))
;;; eof
;;; adbmal-test-s48.scm
(define-structure adbmal
(export test-v1 test-w1 test-p1 test-q1 test-m1 test-n1
test-v2 test-w2 test-p2 test-q2 test-m2 test-n2
((dotimes adbmal mu nu) :syntax))
(open scheme)
(files adbmal-test))
;;; eof
;;; adbmal-test.scm
(define-syntax mu
(syntax-rules ()
((mu . e)
(lambda (f) (f . e)))))
(define-syntax nu
(syntax-rules ()
((nu . e)
(lambda (f) (apply f . e)))))
(define-syntax dotimes
(syntax-rules ()
((dotimes (i count) b d ...)
(do ((i 0 (+ i 1)))
((= i count))
b d ...))
((dotimes count b d ...)
(do ((i 0 (+ i 1)))
((= i count))
b d ...))))
(define-syntax adbmal
(syntax-rules (unquote-splicing)
((adbmal "" (a ...)) (lambda (f) (f a ...)))
((adbmal "" (a ...) , at b) (lambda (f) (apply f a ... b)))
((adbmal "" (a ...) b . e) (adbmal "" (a ... b) . e))
((adbmal . e) (adbmal "" () . e))))
;; If the following syntax is allowed,
;; it can be used instead of the above.
;; (define-syntax adbmal
;; (syntax-rules (unquote-splicing)
;; ((adbmal a ... , at b) (lambda (f) (apply f a ... b)))
;; ((adbmal a ...) (lambda (f) (f a ...)))))
(define v (lambda (x)
(if (< x 0)
(values 1 2 3 11 12 13 14 15)
(if (= x 0)
(values 4 5 6 11 12 13 14 15)
(values 7 8 9 11 12 13 14 15)))))
(define w (lambda (x)
(if (< x 0)
(apply values 1 2 3 '(11 12 13 14 15))
(if (= x 0)
(apply values 4 5 6 '(11 12 13 14 15))
(apply values 7 8 9 '(11 12 13 14 15))))))
(define p (lambda (x)
(if (< x 0)
(lambda () (values 1 2 3 11 12 13 14 15))
(if (= x 0)
(lambda () (values 4 5 6 11 12 13 14 15))
(lambda () (values 7 8 9 11 12 13 14 15))))))
(define q (lambda (x)
(if (< x 0)
(lambda () (apply values 1 2 3 '(11 12 13 14 15)))
(if (= x 0)
(lambda () (apply values 4 5 6 '(11 12 13 14 15)))
(lambda () (apply values 7 8 9 '(11 12 13 14
15)))))))
(define m (lambda (x)
(if (< x 0)
(mu 1 2 3 11 12 13 14 15)
(if (= x 0)
(mu 4 5 6 11 12 13 14 15)
(mu 7 8 9 11 12 13 14 15)))))
(define n (lambda (x)
(if (< x 0)
(nu 1 2 3 '(11 12 13 14 15))
(if (= x 0)
(nu 4 5 6 '(11 12 13 14 15))
(nu 7 8 9 '(11 12 13 14 15))))))
(define (test-v1)
(dotimes (i 5000000)
(call-with-values (lambda () (v i)) +)))
(define (test-w1)
(dotimes (i 5000000)
(call-with-values (lambda () (w i)) +)))
(define (test-p1)
(dotimes (i 5000000)
(call-with-values (p i) +)))
(define (test-q1)
(dotimes (i 5000000)
(call-with-values (q i) +)))
(define (test-m1)
(dotimes (i 5000000) ((m i) +)))
(define (test-n1)
(dotimes (i 5000000) ((n i) +)))
(define (test-v2)
(dotimes (i 5000000)
(call-with-values (lambda () (v i))
(lambda (x1 x2 x3 x4 x5 x6 x7 x8)
(+ x1 x2 x3 x4 x5 x6 x7 x8)))))
(define (test-w2)
(dotimes (i 5000000)
(call-with-values (lambda () (w i))
(lambda (x1 x2 x3 x4 x5 x6 x7 x8)
(+ x1 x2 x3 x4 x5 x6 x7 x8)))))
(define (test-p2)
(dotimes (i 5000000)
(call-with-values (p i)
(lambda (x1 x2 x3 x4 x5 x6 x7 x8)
(+ x1 x2 x3 x4 x5 x6 x7 x8)))))
(define (test-q2)
(dotimes (i 5000000)
(call-with-values (q i)
(lambda (x1 x2 x3 x4 x5 x6 x7 x8)
(+ x1 x2 x3 x4 x5 x6 x7 x8)))))
(define (test-m2)
(dotimes (i 5000000)
((m i) (lambda (x1 x2 x3 x4 x5 x6 x7 x8)
(+ x1 x2 x3 x4 x5 x6 x7 x8)))))
(define (test-n2)
(dotimes (i 5000000)
((n i) (lambda (x1 x2 x3 x4 x5 x6 x7 x8)
(+ x1 x2 x3 x4 x5 x6 x7 x8)))))
;;; eof
The results of these limited tests did not come up to my expectations:
1. The test-1 would be more rapid than the test-2.
2. The test-p & test-q would be more rapid than the test-v & test-w.
(Mzscheme is worthy of notice.)
3. The test-m & test-n would be more slow than the test-v & test-w.
(Larceny is worthy of notice.
It seems to be related with the number of arguments.)
petite larceny scheme48 scheme48 mzscheme
ms-win ms-win linux ms-win ms-win
7.4 0.961 0.57 1.8 3.99.0.23
plain plain plain module plain module plain module
v1 16.2 15.4 35.1 19.9 30.0 19.1 4.1 3.5
p1 15.9 14.9 33.7 22.0 29.3 18.2 9.8* 8.5*
m1 14.9 6.0* 31.0 21.8 25.7 18.2 4.0 3.1
v2 29.2 12.1 38.5 16.4 33.6 17.2 3.6 3.3
p2 29.3 11.4 36.8 18.7 32.6 16.0 10.5* 9.1*
m2 28.1 2.1* 33.9 19.5 28.9 16.0 4.2 3.4
w1 17.8 22.2 43.8 28.3 36.5 25.2 6.9 6.7
q1 17.1 24.4 42.5 30.5 35.8 24.3 16.5* 15.8*
n1 15.9 12.8* 35.5 24.9 30.3 20.5 6.2 5.8
w2 31.4 18.2 44.3 21.6 39.1 21.7 6.1 6.1
q2 30.8 18.5 43.2 24.0 38.3 20.8 16.9* 17.4*
n2 29.5 9.1* 35.8 19.8 28.9 16.6 6.6 6.2
(The second is a unit of this table.)
--
Joo ChurlSoo