Saturday, 4 May 2019

Qi, Lisp and O'Caml compared - performance shootout

An old article by Mark Tarver reproduced here for historical interest:

This test was conducted to determine the relative efficiency and code size of hand-coded Lisp, O'Caml and Qi Turbo-E using the benchmark challenge provided by Jon Harrop.  Dr Harrop also provided the Lisp source written by Andre Thieme, Nathan Forster and Pascal Constanza.
Thanks to many people who corrected these tests and made them possible.
Turbo-E is an unreleased version of Qi which factorises its pattern-matching.
Jon Harrop Challenge Problem
Posted by Dr Harrop
The problem is to simplify symbolic expressions by applying the following rewrite rules from the leaves up:
rational n + rational m -> rational(n + m)
rational n * rational m -> rational(n * m)
symbol x -> symbol x
0+f -> f
f+0 -> f
0*f -> 0
f*0 -> 0
1*f -> f
f*1 -> f
a+(b+c) -> (a+b)+c
a*(b*c) -> (a*b)*c
Thanks to

Nathan Froyd
Andre Thieme
Pascal Constanza
Dan Bensen

for providing code

Jon Harrop (for both providing code and providing motivation to develop Turbo-E)
Marcus Breing (for correcting my first run)
The Results
The benchmark was to simplify [* x [+ [+ [* 12 0] [+ 23 8]] y]]. 10^7 iterations were used as the benchmark. A 2.6GHz, 500Mb RAM machine was used to drive the test. Windows XP was the OS. Times measure only processor time (not real time) and are rounded to 1/10th of a second.
A 2.6GHz, 500Mb RAM machine was used to drive the test. Windows XP was the OS. Times measure only processor time (not real time) and are rounded to 1/10th of a second.
Key:
SBCL 1.0 
Qi Turbo-E under SBCL 1.0 
O'Caml 3.09.3 
 
Mark
Nathan
Andre
Pascal
Dan
Jon
time
3.6s
3.4s
15s
8.2s
5.1s
2.0s
loc
15
39
23
24
34
15
time vs OCaml1.8x1.7x7.5x4.1x2.6x1x
The timer used in Lisp was
(defun tt (N) (gc) (time (test N)))

(defun test (N)
(cond ((zerop N) 0)
(t (simplify *expr*) (test (1- N)))))
took .2 s for 10^7 iterations with (simplify *expr*) removed. All timings were adjusted by deducting .2s from each.
I could run Jon 's solution in interpreted mode, but could not get my O'Caml compiler to work. Based on the ratio of interpreted time to his compiled time, I could construct a projected time.
The Solutions
Here are the solutions; you can download the code here.
Language: Qi
Author: Mark Tarver
Length: 15 lines
(define simplify
  [Op A B] -> (s Op (simplify A) (simplify B))
  A -> A)
(define s
  + M N -> (+ M N)      where (and (number? M) (number? N))
  + 0 F -> F
  + F 0 -> F
  + A [+ B C] -> (simplify [+ [+ A B] C])
  * M N -> (* M N)    where (and (number? M) (number? N))
  * 0 F -> 0
  * F 0 -> 0
  * F 1 -> F
  * 1 F -> F
  * A [* B C] -> (simplify [* [* A B] C])
  Op A B -> [Op A B])
* Note I have used prefix notation for this problem though Dr Harrop's formulation uses infix. The first Lisp solutions followed prefix and so I chose to make my program comparable.*
The generated code is
(DEFUN simplify (V148)
(BLOCK NIL
(TAGBODY
(IF (CONSP V148)
(LET ((Cdr159 (CDR V148)))
(IF (CONSP Cdr159)
(LET ((Cdr158 (CDR Cdr159)))
(IF (CONSP Cdr158)
(IF (NULL (CDR Cdr158))
(RETURN
(s (CAR V148) (simplify (CAR Cdr159))
(simplify (CAR Cdr158))))
(GO tag154))
(GO tag154)))
(GO tag154))))
tag154
(RETURN V148))))

(DEFUN s (V149 V150 V151)
(BLOCK NIL
(TAGBODY
(IF (EQ '+ V149)
(IF (AND (NUMBERP V150) (NUMBERP V151))
(RETURN (THE NUMBER (+ V150 V151)))
(IF (EQL 0 V150) (RETURN V151)
(IF (EQL 0 V151) (RETURN V150)
(IF (CONSP V151)
(LET ((Cdr170 (CDR V151)))
(IF (EQ '+ (CAR V151))
(IF (CONSP Cdr170)
(LET ((Cdr169 (CDR Cdr170)))
(IF (CONSP Cdr169)
(IF (NULL (CDR Cdr169))
(RETURN
(simplify
(CONS '+
(CONS
(LIST '+ V150
(CAR Cdr170))
Cdr169))))
(GO tag160))
(GO tag160)))
(GO tag160))
(GO tag160)))
(GO tag160))))))
tag160
(TAGBODY
(IF (EQ '* V149)
(IF (AND (NUMBERP V150) (NUMBERP V151))
(RETURN (THE NUMBER (* V150 V151)))
(IF (EQL 0 V150) (RETURN 0)
(IF (EQL 0 V151) (RETURN 0)
(IF (EQL 1 V151) (RETURN V150)
(IF (EQL 1 V150) (RETURN V151)
(IF (CONSP V151)
(LET ((Cdr183 (CDR V151)))
(IF (EQ '* (CAR V151))
(IF (CONSP Cdr183)
(LET ((Cdr182 (CDR Cdr183)))
(IF (CONSP Cdr182)
(IF (NULL (CDR Cdr182))
(RETURN
(simplify
(CONS '*
(CONS
(LIST '* V150
(CAR
Cdr183))
Cdr182))))
(GO tag171))
(GO tag171)))
(GO tag171))
(GO tag171)))
(GO tag171))))))))
tag171
(RETURN (LIST V149 V150 V151))))))
Language: OCaml
Author: Jon Harrop
Length: 15 lines
let rec ( +: ) f g = match f, g with
  | `Int n, `Int m -> `Int (n +/ m)
  | `Int (Int 0), e | e, `Int (Int 0) -> e
  | f, `Add(g, h) -> f +: g +: h
  | f, g -> `Add(f, g)
let rec ( *: ) f g = match f, g with
  | `Int n, `Int m -> `Int (n */ m)
  | `Int (Int 0), e | e, `Int (Int 0) -> `Int (Int 0)
  | `Int (Int 1), e | e, `Int (Int 1) -> e
  | f, `Mul(g, h) -> f *: g *: h
  | f, g -> `Mul(f, g)
let rec simplify = function
  | `Int _ | `Var _ as f -> f
  | `Add (f, g) -> simplify f +: simplify g
  | `Mul (f, g) -> simplify f *: simplify g
Language: Lisp
Author: Andre Thieme
Length: 23 lines
(defun simplify (a)
   (if (atom a)
       a
       (destructuring-bind (op x y) a
        (let* ((f (simplify x))
               (g (simplify y))
               (nf (numberp f))
               (ng (numberp g))
               (+? (eq '+ op))
               (*? (eq '* op)))
          (cond
            ((and +? nf ng)                   (+ f g))
            ((and +? nf (zerop f))            g)
            ((and +? ng (zerop g))            f)
            ((and (listp g) (eq op (first g)))
             (destructuring-bind (op2 u v) g
               (simplify `(,op (,op ,f ,u) ,v))))
            ((and *? nf ng)                   (* f g))
            ((and *? (or (and nf (zerop f))
                         (and ng (zerop g)))) 0)
            ((and *? nf (= 1 f))              g)
            ((and *? ng (= 1 g))              f)
            (t                                `(,op ,f ,g)))))))
Language: Lisp
Author: Nathan Froyd
Length: 39 lines
(defun simplify-no-redundant-checks (xexpr)
    (if (atom xexpr)
      xexpr
      (let ((op (first xexpr))
            (z (second xexpr))
            (y (third xexpr)))
        (let* ((f (simplify-no-redundant-checks z))
               (g (simplify-no-redundant-checks y))
               (nf (numberp f))
               (ng (numberp g)))
          (tagbody
           START
             (if (eq '+ op) (go OPTIMIZE-PLUS) (go TEST-MULTIPLY))
           OPTIMIZE-PLUS
             (when (and nf ng) (return-from simplify-no-redundant-checks (+ f g)))
           TEST-PLUS-ZEROS
             (when (eql f 0) (return-from simplify-no-redundant-checks g))
             (when (eql g 0) (return-from simplify-no-redundant-checks f))
             (go REARRANGE-EXPR)
           TEST-MULTIPLY
             (unless (eq '* op) (go REARRANGE-EXPR))
           OPTIMIZE-MULTIPLY
             (when (and nf ng) (return-from simplify-no-redundant-checks (* f g)))
           TEST-MULTIPLY-ZEROS-AND-ONES
             (when (or (eql f 0) (eql g 0)) (return-from simplify-no-redundant-checks 0))
             (when (eql f 1) (return-from simplify-no-redundant-checks g))
             (when (eql g 1) (return-from simplify-no-redundant-checks f))
         REARRANGE-EXPR
             (when (and (listp g) (eq op (first g)))
               (let ((op2 (first g))
                     (u (second g))
                     (v (third g)))
                 (declare (ignore op2))
                 (return-from simplify-no-redundant-checks
                   (simplify-no-redundant-checks (list op (list op f u) v)))))
           MAYBE-CONS-EXPR
             (if (and (eq f z) (eq g y))
                 (return-from simplify-no-redundant-checks xexpr)
                 (return-from simplify-no-redundant-checks (list op f g))))))))
Language: Lisp
Author: Pascal Constanza
Length: 25 lines
(defstruct add x y)
(defstruct mul x y)
(defgeneric simplify-add (x y)
   (:method ((x number) (y number)) (+ x y))
   (:method ((x (eql 0)) y) y)
   (:method (x (y (eql 0))) x)
   (:method (x (y add))
    (simplify-add (simplify-add x (add-x y)) (add-y y)))
   (:method (x y) (make-add :x x :y y)))
(defgeneric simplify-mul (x y)
    (:method ((x number) (y number)) (* x y))
   (:method ((x (eql 0)) y) 0)
   (:method (x (y (eql 0))) 0)
   (:method ((x (eql 1)) y) y)
   (:method (x (y (eql 1))) x)
   (:method (x (y mul))
    (simplify-mul (simplify-mul x (mul-x y)) (mul-y y)))
   (:method (x y) (make-mul :x x :y y)))
(defgeneric simplify (exp)
   (:method (exp) exp)
   (:method ((exp add))
    (simplify-add (simplify (add-x exp)) (simplify (add-y exp))))
   (:method ((exp mul))
    (simplify-mul (simplify (mul-x exp)) (simplify (mul-y exp)))))
Language: Lisp
Author: Dan Bensen
Length: 34 lines
(defmacro defop (func op op-symbl ident zero-case)
  (let ((e1 (gensym "E1"))
         (e2 (gensym "E2")))
     `(defun ,func (,e1 ,e2)
       (declare (optimize (speed 3)))
        ,(delete :no-case
          `(case ,e1
            ,zero-case
            (,ident ,e2)
            (t ,(delete :no-case
               `(case ,e2
                ,zero-case
                (,ident ,e1)
                (t (cond
                   ((and (rationalp ,e1)
                         (rationalp ,e2))
                    (,op ,e1 ,e2))
                   ((atom ,e2)
                    (list ,e1 ,op-symbl ,e2))
                   (t (case
                        (cadr ,e2)
                      (,op-symbl (,func (,func ,e1 (car ,e2))
                                        (caddr ,e2)))
                      (t  (list ,e1 ,op-symbl ,e2))))))))))))))
(defop apply+ + '+ 0 :no-case)
(defop apply* * '* 1 ( 0  0 ))
(defun simplify (expr)
   (if (atom expr)
       expr
     (let ((e1 (simplify (car   expr)))
           (e2 (simplify (caddr expr))))
       (case (cadr expr)
             ('+ (apply+ e1 e2))
             ('* (apply* e1 e2))))))

7 comments:

Saurabh Goud said...


Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Saurabh Goud said...


Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Saurabh Goud said...


Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Saurabh Goud said...


Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Saurabh Goud said...


Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Chalu Baba
Website Blog Ko Hack Se Kaise Bachaye
mobile me software kaise dale
Computer shortcut key
pdf file kya hai
mobile fast charge kaise kre
Facebook password hack kaise kre
Gb whatsapp kya hai
google Image search
Wordpress blog backup kaise le

Gopal Singh said...

thank your sir for sharing this helpful article with us

Alex williams said...

We support all types of HP printer troubleshooting and service. Just enter the model number of your printer in 123.hp.com/setup to identify the software and drivers your printer requires. Download and install it in your mac and 'Run' the file. The process is easy however if you have any doubts or queries regarding HP printers contact us.