Last active
October 26, 2019 06:38
-
-
Save jackfirth/876bbf8802ddd6864872f250d3b96a47 to your computer and use it in GitHub Desktop.
Benchmark comparing Rebellion's sorting transducer against using `(take (sort (sequence->list seq) ...) ...)`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
(require math/number-theory | |
racket/random | |
rebellion/base/option | |
rebellion/collection/entry | |
rebellion/collection/hash | |
rebellion/collection/list | |
rebellion/streaming/reducer | |
rebellion/streaming/transducer | |
rebellion/type/record | |
rebellion/type/wrapper) | |
(define-record-type gemstone (kind weight)) | |
(define (random-gemstone weight) | |
(gemstone #:kind (random-ref (set 'ruby 'sapphire 'emerald 'topaz)) | |
#:weight (random 1 (add1 weight)))) | |
(define (random-gems count) | |
(for/vector ([_ (in-range count)]) | |
(random-gemstone count))) | |
(define (bottom-10/racket gems) | |
(take (sort (sequence->list gems) < #:key gemstone-weight) 10)) | |
(define (bottom-10/rebellion gems) | |
(transduce gems | |
(sorting #:key gemstone-weight) | |
(taking 10) | |
#:into into-list)) | |
(define-record-type timing-data (label cpu-time real-time gc-time)) | |
(define (measure-runtime label thunk) | |
(define-values (_ cpu real gc) (time-apply thunk empty-list)) | |
(timing-data #:label label #:cpu-time cpu #:real-time real #:gc-time gc)) | |
(define (bottom-10-benchmark input-length) | |
(define gems (random-gems input-length)) | |
(set (measure-runtime "Standard racket sort (milliseconds)" | |
(λ () (bottom-10/racket gems))) | |
(measure-runtime "Rebellion lazy sort (milliseconds)" | |
(λ () (bottom-10/rebellion gems))))) | |
(define-record-type stats (sum count max min average)) | |
(define (single-datum-stats x) | |
(stats #:sum x #:count 1 #:max x #:min x #:average x)) | |
(define (stats+ s p) | |
(define sum (+ (stats-sum s) (stats-sum p))) | |
(define count (+ (stats-count s) (stats-count p))) | |
(stats #:sum sum | |
#:count count | |
#:max (max (stats-max s) (stats-max p)) | |
#:min (min (stats-min s) (stats-min p)) | |
#:average (/ sum count))) | |
(define into-stats | |
(make-fold-reducer | |
(λ (accumulated next) | |
(option-case accumulated | |
#:present (λ (acc) (present (stats+ acc next))) | |
#:absent (λ () (present next)))) | |
absent | |
#:name 'into-stats)) | |
(define (run-benchmark benchmark #:size size #:iterations iterations) | |
(transduce (make-list iterations size) | |
(append-mapping benchmark) | |
(bisecting timing-data-label timing-data-cpu-time) | |
(mapping-values single-datum-stats) | |
(grouping into-stats) | |
(mapping-values present-value) | |
#:into into-hash)) | |
(module+ main | |
(run-benchmark bottom-10-benchmark | |
#:size 1000 | |
#:iterations 10)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment