;;; Test the scaling of various lisplab methods to see ;;; if performance is OK. ;;; ;;; Outputs a gnuplot script. ;;; Open gnuplot and load the file. ;;; Findings: ;;; o The complex functions are very slow (in-package :lisplab-user) (defun run-all-scaling-tests () (report-function-times "test-function-scaling.plt") (format t "Writes ~%") (report-operator-times "test-operator-scaling.plt") (format t "Writes ~%")) (defun seconds-of-internal-real-time (fun) "A primitive timer" (let ((start (get-internal-real-time))) (funcall fun) (let ((end (get-internal-real-time))) (/ (- end start) 1.0 INTERNAL-TIME-UNITS-PER-SECOND)))) (defun get-times (fun inputs N) (mapcar (lambda (x) (/ (loop for i from 0 below N sum (seconds-of-internal-real-time (lambda () (apply fun x)))) N)) inputs)) (defun write-gnuplot-scaling (file ns times titles) "Writes a file that can be loaded in gnuplot. Title and ns are list while times is lists of lists with length of the titles." (with-open-file (out file :direction :output :if-exists :supersede) (format out "set logscale x~%") (format out "set logscale y~%") (format out "set key left~%") (format out "plot ") (mapc (lambda (title next) (format out " '-' ti '~a' w lp, " title)) titles (cdr titles)) (format out " '-' ti '~a' w lp" (car (last titles))) (format out "~%") (mapc (lambda (times) (mapc (lambda (n time) (format out "~f ~f~%" n time)) ns times) (format out "e~%")) times))) (defun time-functions (funs mats N) "Average of N runs" (mapcar (lambda (fun) (get-times fun mats N)) funs)) (defun special-functions () '(.erf .erfc .gamma)) (defun ordinary-functions () '(.ln .exp .sin .cos .tan .asin .acos .atan .sinh .cosh .tanh .asinh .acosh .atanh .abs .re .im .conj)) (defun matrix-functions () '(mmax mmin mabsmax mabsmin ll::mminmax)) (defun report-function-times (filename &key (ns '(10 20 50 100 250 500 1000)) (avg 10) (funs (ordinary-functions)) (titles (mapcar #'symbol-name funs)) (mats (mapcar (lambda (n) (drandom N N)) ns))) (let* ((times (time-functions funs (mapcar #'list mats) avg))) (write-gnuplot-scaling filename ns times titles) :end)) (defun ordinary-operators () '(.+ .- .* ./ .^ )) (defun ordinary-operators-real () '(.+ .- .* ./ .^ .max .min .= ./= .< .> .<= .>=)) (defun report-operator-times (filename &key (ns '(10 20 50 100 250 500 1000)) (avg 10) (funs (ordinary-operators-real)) (titles (mapcar #'symbol-name funs)) (lmats (mapcar (lambda (n) (drandom N N)) ns)) (rmats (mapcar (lambda (n) (drandom N N)) ns))) (let* ((times (time-functions funs (mapcar #'list lmats rmats) avg))) (write-gnuplot-scaling filename ns times titles) :end))