355 lines
11 KiB
Scheme
Executable File
355 lines
11 KiB
Scheme
Executable File
#!/bin/sh
|
|
#|
|
|
exec mzscheme -qu "$0" ${1+"$@"}
|
|
|#
|
|
|
|
(module auto scheme/base
|
|
(require (for-syntax scheme/base)
|
|
mzlib/process
|
|
"cmdline.ss"
|
|
mzlib/list
|
|
mzlib/compile
|
|
mzlib/inflate
|
|
mzlib/date
|
|
dynext/file
|
|
syntax/toplevel)
|
|
|
|
;; Implementaton-specific control functions ------------------------------
|
|
|
|
(define (bytes->number b)
|
|
(string->number (bytes->string/latin-1 b)))
|
|
|
|
(define ((run-mk script) bm)
|
|
(when (file-exists? (symbol->string bm))
|
|
(delete-file (symbol->string bm)))
|
|
(parameterize ([current-command-line-arguments (vector (symbol->string bm))])
|
|
(load script)))
|
|
|
|
(define (clean-up-bin bm)
|
|
(delete-file (symbol->string bm)))
|
|
|
|
(define (clean-up-o1 bm)
|
|
(delete-file (format "~a.o1" bm)))
|
|
|
|
(define (mk-mzscheme bm)
|
|
;; To get compilation time:
|
|
(parameterize ([current-namespace (make-base-namespace)])
|
|
(namespace-require 'scheme/base)
|
|
(load (format "~a.ss" bm))))
|
|
|
|
(define (clean-up-nothing bm)
|
|
(void))
|
|
|
|
(define (mk-plt-r5rs bm)
|
|
(with-output-to-file (format "~a.scm" bm)
|
|
#:exists 'replace
|
|
(lambda ()
|
|
(printf "(load \"r5rs-wrap.ss\")\n(load \"~a.sch\")\n" bm)))
|
|
;; To get compilation time:
|
|
(parameterize ([current-namespace (make-base-empty-namespace)])
|
|
(namespace-require 'r5rs)
|
|
(with-input-from-file (format "~a.sch" bm)
|
|
(lambda ()
|
|
(let loop ()
|
|
(let ([e (read-syntax)])
|
|
(unless (eof-object? e)
|
|
(eval-compile-time-part-of-top-level/compile
|
|
(namespace-syntax-introduce e))
|
|
(loop))))))))
|
|
|
|
(define (clean-up-plt-r5rs bm)
|
|
(let ([f (format "~s.scm" bm)])
|
|
(when (file-exists? f)
|
|
(delete-file f))))
|
|
|
|
(define (mk-mzscheme-tl bm)
|
|
;; To get compilation time:
|
|
(parameterize ([current-namespace (make-base-namespace)])
|
|
(namespace-require 'scheme/base)
|
|
(eval '(define null #f)) ; for dynamic.sch
|
|
(compile-file (format "~a.sch" bm))))
|
|
|
|
(define (clean-up-zo bm)
|
|
(delete-file (build-path "compiled" (format "~a.zo" bm))))
|
|
|
|
(define (mk-larceny bm)
|
|
(parameterize ([current-input-port
|
|
(open-input-string
|
|
(format (string-append
|
|
"(compiler-switches 'fast-safe)\n"
|
|
"(compile-file \"~a.sch\")\n")
|
|
bm))]
|
|
[current-output-port (open-output-bytes)])
|
|
(system "larceny")))
|
|
|
|
(define (clean-up-fasl bm)
|
|
(delete-file (format "~a.fasl" bm)))
|
|
|
|
(define (mk-mzc bm)
|
|
(parameterize ([current-output-port (open-output-bytes)])
|
|
(system (format "mzc ~a.ss" bm))))
|
|
|
|
(define (clean-up-extension bm)
|
|
(delete-file (append-extension-suffix (symbol->string bm))))
|
|
|
|
(define (run-exe bm)
|
|
(system (symbol->string bm)))
|
|
|
|
(define (run-exe/time bm)
|
|
(system (format "time ~a" bm)))
|
|
|
|
(define (run-gambit-exe bm)
|
|
(system (format "gsi -:d-,m10000 ~a.o1" bm)))
|
|
|
|
(define (run-larceny bm)
|
|
(parameterize ([current-input-port (open-input-string
|
|
(format "(load \"~a.fasl\")\n"
|
|
bm))])
|
|
(system "larceny")))
|
|
|
|
(define (mk-ikarus bm)
|
|
(void))
|
|
|
|
(define (run-ikarus bm)
|
|
(system (format "ikarus ~a.sch < /dev/null" bm)))
|
|
|
|
(define (extract-times bm str)
|
|
str)
|
|
|
|
(define (extract-gambit-times bm str)
|
|
(let ([m (regexp-match (byte-regexp
|
|
(bytes-append
|
|
#"([0-9]+) ms real.*[^0-9]"
|
|
#"([0-9]+) ms cpu.*"
|
|
#"(?:no collections|collections? accounting for ([0-9]+) ms.*)"))
|
|
str)])
|
|
(map bytes->number
|
|
(list (caddr m)
|
|
(cadr m)
|
|
(or (cadddr m) #"0")))))
|
|
|
|
(define (extract-mzscheme-times bm str)
|
|
(let ([m (regexp-match #rx#"cpu time: ([0-9]+) real time: ([0-9]+) gc time: ([0-9]+)" str)])
|
|
(map bytes->number (cdr m))))
|
|
|
|
(define (extract-larceny-times bm str)
|
|
(let ([m (regexp-match #rx#"Elapsed time...: ([0-9]+) ms.*Elapsed GC time: ([0-9]+) ms" str)])
|
|
(list (bytes->number (cadr m))
|
|
#f
|
|
(bytes->number (caddr m)))))
|
|
|
|
(define (extract-chicken-times bm str)
|
|
(let ([m (regexp-match #rx#"([0-9.]+) seconds.*[^0-9.]([0-9.]+) seconds" str)])
|
|
(list (* 1000 (string->number (format "#e~a" (cadr m))))
|
|
#f
|
|
(* 1000 (string->number (format "#e~a" (caddr m)))))))
|
|
|
|
(define (extract-time-times bm str)
|
|
(let ([m (regexp-match #rx#"real[ \t]+([0-9m.]+)s.*user[ \t]+([0-9m.]+)s.sys[ \t]+([0-9m.]+)s." str)]
|
|
[ms->milliseconds (lambda (s)
|
|
(let ([m (regexp-match "([0-9]+)m([0-9.]+)" s)])
|
|
(+ (* 60000 (string->number (format "~a" (cadr m))))
|
|
(* 1000 (string->number (format "#e~a" (caddr m)))))))])
|
|
(let ([real (ms->milliseconds (cadr m))]
|
|
[user (ms->milliseconds (caddr m))]
|
|
[sys (ms->milliseconds (cadddr m))])
|
|
(list (+ user sys) real #f))))
|
|
|
|
(define (extract-ikarus-times bm str)
|
|
(let ([m (regexp-match (bytes-append
|
|
#"([0-9]*) ms elapsed cpu time, including ([0-9]*) ms collecting\n"
|
|
#"[ \t]*([0-9]*) ms elapsed real time")
|
|
str)])
|
|
(list (string->number (bytes->string/utf-8 (cadr m)))
|
|
(string->number (bytes->string/utf-8 (cadddr m)))
|
|
(string->number (bytes->string/utf-8 (caddr m))))))
|
|
|
|
|
|
;; Table of implementatons and benchmarks ------------------------------
|
|
|
|
(define-struct impl (name make run extract-result clean-up skips))
|
|
|
|
(define mutable-pair-progs '(conform
|
|
destruct
|
|
dynamic
|
|
lattice
|
|
maze
|
|
peval
|
|
scheme
|
|
sort1))
|
|
|
|
(define impls
|
|
(list
|
|
(make-impl 'mzscheme
|
|
mk-mzscheme
|
|
(lambda (bm)
|
|
(system (format "mzscheme -u ~a.ss" bm)))
|
|
extract-mzscheme-times
|
|
clean-up-nothing
|
|
mutable-pair-progs)
|
|
(make-impl 'mz-old
|
|
mk-mzscheme
|
|
(lambda (bm)
|
|
(system (format "mz-old -u ~a.ss" bm)))
|
|
extract-mzscheme-times
|
|
clean-up-nothing
|
|
mutable-pair-progs)
|
|
(make-impl 'mzschemecgc
|
|
mk-mzscheme
|
|
(lambda (bm)
|
|
(system (format "mzschemecgc -u ~a.ss" bm)))
|
|
extract-mzscheme-times
|
|
clean-up-nothing
|
|
mutable-pair-progs)
|
|
(make-impl 'plt-r5rs
|
|
mk-plt-r5rs
|
|
(lambda (bm)
|
|
(system (format "plt-r5rs ~a.scm" bm)))
|
|
extract-mzscheme-times
|
|
clean-up-plt-r5rs
|
|
null)
|
|
(make-impl 'mzc
|
|
mk-mzc
|
|
(lambda (bm)
|
|
(system (format "mzscheme -mvqee '(load-extension \"~a\")' '(require ~a)'"
|
|
(append-extension-suffix (symbol->string bm))
|
|
bm)))
|
|
extract-mzscheme-times
|
|
clean-up-extension
|
|
(append '(takr takr2)
|
|
mutable-pair-progs))
|
|
(make-impl 'mzscheme-j
|
|
mk-mzscheme
|
|
(lambda (bm)
|
|
(system (format "mzscheme -jqu ~a.ss" bm)))
|
|
extract-mzscheme-times
|
|
clean-up-nothing
|
|
mutable-pair-progs)
|
|
(make-impl 'mzschemecgc-tl
|
|
mk-mzscheme-tl
|
|
(lambda (bm)
|
|
(system (format "mzschemecgc -qr compiled/~a.zo" bm)))
|
|
extract-mzscheme-times
|
|
clean-up-zo
|
|
(append '(nucleic2)
|
|
mutable-pair-progs))
|
|
(make-impl 'chicken
|
|
(run-mk "mk-chicken.ss")
|
|
run-exe
|
|
extract-chicken-times
|
|
clean-up-bin
|
|
'(nucleic2))
|
|
(make-impl 'bigloo
|
|
(run-mk "mk-bigloo.ss")
|
|
run-exe/time
|
|
extract-time-times
|
|
clean-up-bin
|
|
'(cpstack maze maze2 puzzle triangle))
|
|
(make-impl 'gambit
|
|
(run-mk "mk-gambit.ss")
|
|
run-gambit-exe
|
|
extract-gambit-times
|
|
clean-up-o1
|
|
'(nucleic2))
|
|
(make-impl 'larceny
|
|
mk-larceny
|
|
run-larceny
|
|
extract-larceny-times
|
|
clean-up-fasl
|
|
'(maze maze2))
|
|
(make-impl 'ikarus
|
|
mk-ikarus
|
|
run-ikarus
|
|
extract-ikarus-times
|
|
clean-up-nothing
|
|
'(fft))))
|
|
|
|
(define obsolte-impls '(mzscheme mzscheme-j mzschemecgc-tl mzc))
|
|
|
|
(define benchmarks
|
|
'(conform
|
|
cpstack
|
|
ctak
|
|
deriv
|
|
dderiv
|
|
destruct
|
|
div
|
|
dynamic
|
|
dynamic2
|
|
earley
|
|
fft
|
|
graphs
|
|
lattice
|
|
lattice2
|
|
maze
|
|
maze2
|
|
mazefun
|
|
nboyer
|
|
nestedloop
|
|
nfa
|
|
nqueens
|
|
nucleic2
|
|
paraffins
|
|
peval
|
|
puzzle
|
|
sboyer
|
|
scheme
|
|
scheme2
|
|
sort1
|
|
tak
|
|
takl
|
|
takr
|
|
takr2
|
|
triangle))
|
|
|
|
(define (run-benchmark impl bm)
|
|
(let ([i (ormap (lambda (i)
|
|
(and (eq? impl (impl-name i))
|
|
i))
|
|
impls)])
|
|
(if (memq bm (impl-skips i))
|
|
(rprintf "[~a ~a ~s #f]\n" impl bm '(#f #f #f))
|
|
(let ([start (current-inexact-milliseconds)])
|
|
((impl-make i) bm)
|
|
(let ([end (current-inexact-milliseconds)])
|
|
(let loop ([n num-iterations])
|
|
(unless (zero? n)
|
|
(let ([out (open-output-bytes)])
|
|
(unless (parameterize ([current-output-port out]
|
|
[current-error-port out])
|
|
((impl-run i) bm))
|
|
(error 'auto "~a\nrun failed ~a" (get-output-bytes out) bm))
|
|
(rprintf "[~a ~a ~s ~a]\n"
|
|
impl
|
|
bm
|
|
((impl-extract-result i) bm (get-output-bytes out))
|
|
(inexact->exact (round (- end start)))))
|
|
(loop (sub1 n)))))
|
|
((impl-clean-up i) bm)))
|
|
(flush-output)))
|
|
|
|
;; Extract command-line arguments --------------------
|
|
|
|
(define-values (actual-benchmarks-to-run
|
|
actual-implementations-to-run
|
|
num-iterations)
|
|
(process-command-line benchmarks
|
|
(map impl-name impls) obsolte-impls
|
|
3))
|
|
|
|
;; Benchmark-specific setup --------------------
|
|
|
|
(when (memq 'dynamic actual-benchmarks-to-run )
|
|
(unless (file-exists? "dynamic-input.txt")
|
|
(gunzip "dynamic-input.txt.gz")))
|
|
|
|
;; Run benchmarks -------------------------------
|
|
|
|
(rprintf "; ~a\n" (date->string (seconds->date (current-seconds)) #t))
|
|
|
|
(for-each (lambda (impl)
|
|
(map (lambda (bm)
|
|
(run-benchmark impl bm))
|
|
actual-benchmarks-to-run))
|
|
actual-implementations-to-run))
|