[plt-scheme] Performance inconsistency of call-with-values

From: tilde at tilde.kr (tilde at tilde.kr)
Date: Wed Apr 30 00:18:38 EDT 2008

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 







Posted on the users mailing list.