binary-trees Lisp SBCL #3 program
source code
;; The Computer Language Benchmarks Game
;; https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
;;;
;;; contributed by Roman Kashitsyn
;;;
(deftype uint () '(unsigned-byte 62))
(defconstant min-depth 4 "Minimal depth of the binary tree.")
(defparameter num-workers 4 "Number of concurrent workers.")
(defun build-tree (depth)
"Build a binary tree of the specified DEPTH. Leaves are represented by NIL,
branches are represented by a cons cell."
(declare (ftype (function (uint) list) build-tree)
(uint depth)
(optimize (speed 3) (safety 0)))
(if (zerop depth) (cons nil nil)
(cons (build-tree (1- depth))
(build-tree (1- depth)))))
(defun check-node (node)
(declare (ftype (function (list) uint) check-node)
(optimize (speed 3) (safety 0)))
(if (null (car node))
1
(the uint (+ 1 (check-node (car node)) (check-node (cdr node))))))
(defun check-trees-of-depth (depth max-depth)
(declare (uint depth max-depth)
(optimize (speed 3) (safety 0)))
(loop with iterations of-type uint = (ash 1 (+ max-depth min-depth (- depth)))
for i of-type uint from 1 upto iterations
sum (check-node (build-tree depth))
into result of-type uint
finally (return (format nil "~d~c trees of depth ~d~c check: ~d~%"
iterations #\Tab depth #\Tab result))))
(defun loop-depths-async (max-depth)
(declare (fixnum max-depth))
(let* ((tasks (sb-concurrency:make-queue
:initial-contents
(loop for depth from min-depth by 2 upto max-depth
collect depth)))
(outputs (sb-concurrency:make-queue))
(threads
(loop for i of-type fixnum from 1 to num-workers
collect (sb-thread:make-thread
#'(lambda ()
(loop as task = (sb-concurrency:dequeue tasks)
while task
do (sb-concurrency:enqueue
(cons task
(check-trees-of-depth task max-depth))
outputs)))))))
(mapc #'sb-thread:join-thread threads)
(let ((results (sort (sb-concurrency:list-queue-contents outputs)
#'< :key #'car)))
(loop for (k . v) in results
do (format t "~a" v)))))
(defun binary-trees-upto-size (n)
(declare (type (integer 0 255) n))
(format t "stretch tree of depth ~d~c check: ~d~%" (1+ n) #\Tab
(check-node (build-tree (1+ n))))
(let ((long-lived-tree (build-tree n)))
(loop-depths-async n)
(format t "long lived tree of depth ~d~c check: ~d~%" n #\Tab
(check-node long-lived-tree))))
(defun main (&optional (n (parse-integer (or (car (last sb-ext:*posix-argv*))
"1"))))
(binary-trees-upto-size n))
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
SBCL 2.4.8
Fri, 06 Sep 2024 20:59:03 GMT
MAKE:
cp: 'binarytrees.sbcl-3.sbcl' and './binarytrees.sbcl-3.sbcl' are the same file
SBCL built with: /opt/src/sbcl-2.4.8/bin/sbcl --userinit /dev/null --batch --eval '(load "binarytrees.sbcl-3.sbcl_compile")'
### START binarytrees.sbcl-3.sbcl_compile
(handler-bind ((sb-ext:defconstant-uneql (lambda (c) (abort c)))) (require :sb-concurrency) (load (compile-file "binarytrees.sbcl-3.sbcl" ))) (save-lisp-and-die "sbcl.core" :purify t)
### END binarytrees.sbcl-3.sbcl_compile
; compiling file "/home/dunham/all-benchmarksgame/benchmarksgame_i53330/binarytrees/tmp/binarytrees.sbcl-3.sbcl" (written 01 JAN 2020 03:08:42 PM):
; wrote /home/dunham/all-benchmarksgame/benchmarksgame_i53330/binarytrees/tmp/binarytrees.sbcl-3.fasl
; compilation finished in 0:00:00.091
### START binarytrees.sbcl-3.sbcl_run
(main) (quit)
### END binarytrees.sbcl-3.sbcl_run
2.40s to complete and log all make actions
COMMAND LINE:
/opt/src/sbcl-2.4.8/bin/sbcl --noinform --core sbcl.core --userinit /dev/null --load binarytrees.sbcl-3.sbcl_run 21
PROGRAM OUTPUT:
stretch tree of depth 22 check: 8388607
2097152 trees of depth 4 check: 65011712
524288 trees of depth 6 check: 66584576
131072 trees of depth 8 check: 66977792
32768 trees of depth 10 check: 67076096
8192 trees of depth 12 check: 67100672
2048 trees of depth 14 check: 67106816
512 trees of depth 16 check: 67108352
128 trees of depth 18 check: 67108736
32 trees of depth 20 check: 67108832
long lived tree of depth 21 check: 4194303