123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- (use-modules (charting) (charting csv) (ice-9 match) (ice-9 pretty-print))
- (define (keyed-sorter key less?)
- (lambda (a b) (less? (key a) (key b))))
- (define (group-by ls less? truncate zero add)
- (let lp ((ls (sort ls (keyed-sorter truncate less?)))
- (cur #f)
- (sum (zero)))
- (define (finish tail)
- (if cur
- (acons cur sum tail)
- tail))
- (match ls
- (() (finish '()))
- ((x . ls)
- (let ((x_ (truncate x)))
- (if (equal? x_ cur)
- (lp ls cur (add x sum))
- (finish (lp ls x_ (add x (zero))))))))))
- (define (median ls)
- (let* ((ordered (list->vector (sort ls <)))
- (len (vector-length ordered)))
- (if (even? len)
- (/ (+ (vector-ref ordered (/ len 2))
- (vector-ref ordered (1- (/ len 2))))
- 2)
- (vector-ref ordered (/ (1- len) 2)))))
- (define (sort-by-first-non-baseline tests)
- (let ((medians
- (match tests
- ((baseline
- (non-baseline (test . times) ...)
- . _)
- (map cons test (map median times))))))
- (define (extract-median test)
- (match test
- ((name . times)
- (or (assoc-ref medians name) 0.0))))
- (match tests
- (((baseline . tests) . rest)
- (cons (cons baseline (sort tests (keyed-sorter extract-median <)))
- rest)))))
- (match (program-arguments)
- ((_ title output input)
- (let* ((rows (call-with-input-file input csv-port->row-list))
- (by-version
- (group-by rows
- string<?
- (match-lambda
- (#(version test time) version))
- (lambda () '())
- (lambda (row data)
- (match row
- (#(version test time)
- (acons test (string->number time) data))))))
- (by-version-and-test
- (map (lambda (test)
- (match test
- ((version . data)
- (cons version
- (group-by data
- string<?
- (match-lambda
- ((test . time) test))
- (lambda () '())
- (lambda (data times)
- (match data
- ((test . time)
- (cons time times)))))))))
- by-version))
- (normalized
- (let ((norms (match by-version-and-test
- (((version . tests) . _)
- (map (match-lambda
- ((test . times)
- (cons test (median times))))
- tests)))))
- (map (lambda (test)
- (match test
- ((version . data)
- (cons version
- (map (match-lambda
- ((test . times)
- (let ((norm (or (assoc-ref norms test) 1.0)))
- (cons test
- (map (lambda (time) (/ time norm))
- times)))))
- data)))))
- by-version-and-test)))
- (sorted (sort-by-first-non-baseline normalized)))
- (make-performance-chart
- title
- sorted
- #:log-y-base 2
- #:y-axis-label
- (match sorted
- (((version . _) . _)
- (format #f "run time normalized to ~a; shorter is better" version)))
- #:baseline 1.0
- #:box-width 5
- #:box-spacing 0
- #:test-spacing 10
- #:vertical-xtick-labels? #t
- #:vertical-box-labels? #t
- #:box-label-height 8.5
- #:box-value-formatter
- (lambda (value)
- (let ((str (format #f "~,3f" value)))
- (if (equal? str "1.000")
- ""
- str)))
- #:write-to-png output))))
|