diff --git a/sources/testing/benchmarks/write-100mb/README.rst b/sources/testing/benchmarks/write-100mb/README.rst new file mode 100644 index 000000000..ff4e2debf --- /dev/null +++ b/sources/testing/benchmarks/write-100mb/README.rst @@ -0,0 +1,14 @@ +Write 10_000MB, best of three runs on an Apple M3 Pro, May 2024: + + Python SBCL Dylan Racket +real 7.500s 13.837s 23.425s 30.620s + 1.0x 1.8x 3.1x 4.1x +user 4.837s 11.334s 6.455s 21.053s + 1.0x 2.3x 1.3x 4.4x +sys 2.286s 2.368s 10.749s 7.031s + + +Note that the other implementations are using Unicode so comparison isn't +really fair. In particular, Racket does better than SBCL if the test is changed +to use a byte string (#"xxx") but has a particularly pessimized Unicode path, +it seems. diff --git a/sources/testing/benchmarks/write-100mb/write-100mb.dylan b/sources/testing/benchmarks/write-100mb/write-100mb.dylan index 6982931c0..fc211f580 100644 --- a/sources/testing/benchmarks/write-100mb/write-100mb.dylan +++ b/sources/testing/benchmarks/write-100mb/write-100mb.dylan @@ -3,9 +3,12 @@ Module: write-100mb define function main () let string = make(, size: 100, fill: 'x'); - with-open-file (stream = "/tmp/100mb.dylan.txt", direction: #"output") - for (i from 1 to 1024 * 1024) - write(stream, string); + for (o from 1 to 100) + with-open-file (stream = "/tmp/100mb.dylan.txt", + direction: #"output") + for (i from 1 to 1024 * 1024) + write(stream, string); + end; end; end; end function; diff --git a/sources/testing/benchmarks/write-100mb/write-100mb.lisp b/sources/testing/benchmarks/write-100mb/write-100mb.lisp index 1cea66a04..143adaecd 100644 --- a/sources/testing/benchmarks/write-100mb/write-100mb.lisp +++ b/sources/testing/benchmarks/write-100mb/write-100mb.lisp @@ -1,9 +1,11 @@ (in-package :cl-user) -(defun write-100mb () +(defun write-10000mb () + ;; (declare (optimize (speed 3) (debug 0))) (let ((string (make-string 100 :initial-element #\x))) - (with-open-file (stream "/tmp/100mb.sbcl.txt" :direction :output :if-exists :supersede) - (loop repeat (* 1024 1024) - do (write-string string stream))))) + (loop repeat 100 + do (with-open-file (stream "/tmp/100mb.sbcl.txt" :direction :output :if-exists :supersede) + (loop repeat (* 1024 1024) + do (write-string string stream)))))) -(write-100mb) +;;; sbcl --noinform --no-sysinit --no-userinit --eval '(load "write-100mb.lisp")' --eval '(sb-ext:save-lisp-and-die #P"/tmp/clwrite100mb" :executable t :toplevel 'cl-user::write-10000mb)' diff --git a/sources/testing/benchmarks/write-100mb/write-100mb.rkt b/sources/testing/benchmarks/write-100mb/write-100mb.rkt new file mode 100644 index 000000000..d638de7d4 --- /dev/null +++ b/sources/testing/benchmarks/write-100mb/write-100mb.rkt @@ -0,0 +1,20 @@ +#lang racket/base + +(require racket/port) + +(define (write-10000mb) + ;; Use #"xxx" to write a byte string instead. MUCH faster. + (let ((string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")) + (let outer ((o 100)) + (when (> o 0) + (call-with-output-file + #:exists 'truncate + "/tmp/100mb.racket.txt" + (lambda (port) + (let loop ((n (* 1024 1024))) + (when (> n 0) + (display string port) + (loop (- n 1)))))) + (outer (- o 1)))))) + +(write-10000mb) diff --git a/sources/testing/benchmarks/write-100mb/write_100mb.py b/sources/testing/benchmarks/write-100mb/write_100mb.py index 699973191..76c95fb36 100755 --- a/sources/testing/benchmarks/write-100mb/write_100mb.py +++ b/sources/testing/benchmarks/write-100mb/write_100mb.py @@ -2,9 +2,10 @@ def main (): s = "x" * 100 - with open("/tmp/100mb.python.txt", "w") as fd: - for i in range(1024 * 1024): - fd.write(s) + for x in range(100): + with open("/tmp/100mb.python.txt", "w") as fd: + for i in range(1024 * 1024): + fd.write(s) if __name__ == "__main__": main()