Generic performance added by dieggsy on Fri Jan 29 21:04:19 2021

#!/usr/bin/chicken-scheme
;; AUTOCOMPILE: -O3

(module fg (plus)
  (import scheme
          fast-generic)

  (define-type <list> list?)
  (define-type <string> string?)
  (define-type <number> number?)

  (define-generic (plus (<list> l1) (<list> l2))
    (append l1 l2))

  (define-generic (plus (<string> s1) (<string> s2))
    (string-append s1 s2))

  (define-generic (plus (<number> n1) (<number> n2))
    (+ n1 n2)))

(module cg (plus)
  (import scheme
          chibi-generic)
  (define-generic plus)

  (define-method (plus (l1 list?) (l2 list?))
    (append l1 l2))

  (define-method (plus (s1 string?) (s2 string?))
    (string-append s1 s2))

  (define-method (plus (n1 number?) (n2 number?))
    (+ n1 n2)))

(module cp (plus)
  (import scheme
          coops
          coops-primitive-objects)

  (define-generic (plus arg1 arg2))
  (define-method (plus (l1 <list>) (l2 <list>))
    (append l1 l2))

  (define-method (plus (s1 <string>) (s2 <string>))
    (string-append s1 s2))

  (define-method (plus (n1 <number>) (n2 <number>))
    (+ n1 n2)))

(module gs (plus)
  (import scheme
          (only chicken.base error)
          generic-functions)
  (define-generic (plus l1 l2)
    (error "No type match"))
  (define-method (plus (l1 list??) (l2 list??))
    (append l1 l2))

  (define-method (plus (s1 string??) (s2 string??))
    (string-append s1 s2))

  (define-method (plus (n1 number??) (n2 number??))
    (+ n1 n2)))

(module main ()
  (import scheme
          (only chicken.base print)
          (only chicken.time time)
          (only miscmacros dotimes)
          fast-generic
          (prefix fg fg:)
          (prefix cg cg:)
          (prefix cp cp:)
          (prefix gs gs:))

  (define-type <list> list?)
  (define-type <string> string?)
  (define-type <number> number?)

  (define-generic (fgf:plus (<list> l1) (<list> l2))
    (append l1 l2))

  (define-generic (fgf:plus (<string> s1) (<string> s2))
    (string-append s1 s2))

  (define-generic (fgf:plus (<number> n1) (<number> n2))
    (+ n1 n2))


  (define (plus a b)
    (cond ((and (list? a) (list? b))
           (append a b))
          ((and (string? a) (string? b))
           (string-append a b))
          ((and (number? a) (number? b))
           (+ a b))))

  (print "generics:")
  (print (gs:plus '(1 2 3) '(1 2 3)))
  (time
   (dotimes (i 10000000)
     (gs:plus '(1 2 3) '(1 2 3))))

  (newline)
  (print "coops:")
  (print (cp:plus '(1 2 3) '(1 2 3)))
  (time
   (dotimes (i 10000000)
     (cp:plus '(1 2 3) '(1 2 3))))

  (newline)
  (print "chibi-generic:")
  (print (cg:plus '(1 2 3) '(1 2 3)))
  (time
   (dotimes (i 10000000)
     (cg:plus '(1 2 3) '(1 2 3))))

  (newline)
  (print "fast-generic:")
  (print (fg:plus '(1 2 3) '(1 2 3)))
  (time
   (dotimes (i 10000000)
     (fg:plus '(1 2 3) '(1 2 3))))

  (newline)
  (print "fast-generic (specialization):")
  (print (fgf:plus '(1 2 3) '(1 2 3)))
  (time
   (dotimes (i 10000000)
     (fgf:plus '(1 2 3) '(1 2 3))))

  (newline)
  (print "cond with predicates")
  (print (plus '(1 2 3) '(1 2 3)))
  (time
   (dotimes (i 10000000)
     (plus '(1 2 3) '(1 2 3)))))

;;; Output:

;; generics:
;; (1 2 3 1 2 3)
;; 89.741s CPU time, 1.857s GC time (major), 840000000/519922721 mutations (total/tracked), 3288/992337 GCs (major/minor), maximum live heap: 344.21 KiB

;; coops:
;; (1 2 3 1 2 3)
;; 14.812s CPU time, 0.215s GC time (major), 379/214388 GCs (major/minor), maximum live heap: 343.95 KiB

;; chibi-generic:
;; (1 2 3 1 2 3)
;; 3.194s CPU time, 0.02s GC time (major), 38/37825 GCs (major/minor), maximum live heap: 343.75 KiB

;; fast-generic:
;; (1 2 3 1 2 3)
;; 1.231s CPU time, 0.013s GC time (major), 10000000/12598 mutations (total/tracked), 26/22719 GCs (major/minor), maximum live heap: 343.87 KiB

;; fast-generic (specialization):
;; (1 2 3 1 2 3)
;; 0.875s CPU time, 0.01s GC time (major), 10000000/8002 mutations (total/tracked), 19/14176 GCs (major/minor), maximum live heap: 343.75 KiB

;; cond with predicates
;; (1 2 3 1 2 3)
;; 0.895s CPU time, 0.006s GC time (major), 11/16016 GCs (major/minor), maximum live heap: 343.77 KiB