Happy Sunday Swampers =)
This little project was born out of my need to verify comments like "its faster if you do it this way".
For someone new to LISP like myself, it helps to have some numbers so I know exactly how much weight every
algorithm is contributing to the overall speed in a given project. So I have compiled here a collection of
(10) basic unit tests that compare similar functions and report their speeds relative to one another.
First, let me describe the unit test itself. Using the (apply 'fx 'list) function at its core, a list of functions
is passed to the unit test for processing, along with a max variance constant (bear with me). For each function
in the input list, (1) second is designated for a function to repeat itself and record of the number of iterations
it achieves along the way. Within this time limit, each function is actually tested a number of times (for these
tests, 8 times to be exact) and the iteration count from each run is compiled in a list. From this list, the ratio
between the highest and lowest values is recorded as test run "variance". If the test run variance is above the max
variance constant supplied to the unit test, the function is retested. Once a function has passed the variance
requirement, the test results for that function are considered reliable. The highest and lowest values are then
dropped from the list, and the remaining values are used to calculate an iteration average for the function,
expressed in "kips", which is my notation for kilo-iterations per second. In case it is not obvious, this number is
equivalent to iterations per millisecond. Once all function tests are complete, the results are sorted by kips
in descending order and echoed to the command line. The slowest function in a unit test (the lowest kips rating) is
used as a baseline and assigned a value of 1.0. All other functions are assigned a speed relative to this baseline.
Any questions about this method let me know. I'll be posting the actual code for the unit test after some formatting.
One more thing, dont let small differences fool you. A 5% difference can be wildly compounded in a complex routine.
For example, upon finishing these basic benchmarks, I rewrote a major algorithm I was working on before getting
sidetracked by this quest, and I was able to take it from 0.55 kips to 4.2 kips.. same functionality; faster code.
[EDIT: AutoCAD 2012 results follow]
[LINK to source code:
Another benchmark function]
Test 1: Cond vs If-then-elseFunctions:
(defun tCond
() (cond (nil T
) (nil T
) (T T
) )))
Results:
Unit test 2.00 s kips rel var
------------------------------------------
TCOND 121 1.00 1.02
TIFIF 121 1.00 1.05
------------------------------------------
Completed 241,702 = 121
Test 2: = vs Equal, Int / Real / StrFunctions:
(defun tCmpreInt
() (= 0 0 ))) (defun tCmpreRel
() (= 0.0 0.0))) (defun tCmpreStr
() (= "A" "A")))
Results:
Unit test 6.00 s kips rel var
------------------------------------------
TCMPREREL 116 1.04 1.05
TEQUALINT 115 1.04 1.04
TCMPREINT 114 1.03 1.05
TEQUALREL 113 1.01 1.05
TEQUALSTR 112 1.01 1.05
TCMPRESTR 111 1.00 1.05
------------------------------------------
Completed 680,148 = 113
Test 3: < vs <=Functions:
Results:
Unit test 2.00 s kips rel var
------------------------------------------
TLESSTHAN 66 1.00 1.03
TLESSOREQ 66 1.00 1.01
------------------------------------------
Completed 131,565 = 66
Test 4: Append vs ConsFunctions:
Results:
Unit test 3.00 s kips rel var
------------------------------------------
TCONS 83 1.28 1.02
TCONR 83 1.27 1.03
TAPND 65 1.00 1.03
------------------------------------------
Completed 231,098 = 77
Test 5: Repeat vs WhileFunctions:
Results:
Unit test 3.00 s kips rel var
------------------------------------------
TRPEAT 70 1.13 1.05
TWHILE 67 1.07 1.01
TIPEAT 62 1.00 1.02
------------------------------------------
Completed 198,586 = 66
Test 6: Member vs Vl-position, First / Middle / LastFunctions:
Results:
Unit test 6.00 s kips rel var
------------------------------------------
TVLP0 81 1.10 1.01
TVLP1 80 1.09 1.01
TMEM0 79 1.08 1.02
TVLP2 78 1.07 1.02
TMEM1 75 1.03 1.02
TMEM2 73 1.00 1.02
------------------------------------------
Completed 466,067 = 78
Test 7: Short vs Long function names, Alpha / NumericFunctions:
(defun t0123456789
() T
)) (defun tABCDEFGHIJ
() T
)) (defun t
-B
-D
-F
-H
-J
() T
))
Results:
Unit test 6.00 s kips rel var
------------------------------------------
T_B_D 96 1.03 1.05
T0123 95 1.02 1.01
TABCD 95 1.02 1.04
T0123456789 94 1.01 1.01
TABCDEFGHIJ 94 1.01 1.01
T-B-D-F-H-J 93 1.00 1.04
------------------------------------------
Completed 567,202 = 95
Test 8: CAR / CADR vs NthFunctions:
Results:
Unit test 8.00 s kips rel var
------------------------------------------
TCAR0 82 1.05 1.03
TCAR1 81 1.04 1.01
TCAR2 81 1.04 1.01
TCAR3 80 1.04 1.01
TNTH0 79 1.01 1.02
TNTH1 78 1.01 1.02
TNTH2 78 1.00 1.02
TNTH3 78 1.00 1.02
------------------------------------------
Completed 636,115 = 80
Test 9: (+ i 1) vs (1+ i)Functions:
Results:
Unit test 2.00 s kips rel var
------------------------------------------
TPLUS1 93 1.00 1.01
T1PLUS 93 1.00 1.01
------------------------------------------
Completed 185,470 = 93
Test 10: Predicates vs Type CheckingFunctions:
(defun tEqZeroS
() (= "" "" )))
Results:
Unit test 15.00 s kips rel var
------------------------------------------
TNOCHECK 121 1.20 1.06
TNULLVAL 119 1.18 1.09
TEQZEROR 119 1.18 1.05
TSYMPRED 119 1.17 1.07
TNUMBERI 119 1.17 1.06
TEQZEROI 119 1.17 1.09
TLSTPRED 118 1.17 1.05
TNUMBERR 117 1.15 1.10
THASAVAL 116 1.15 1.06
TTYPELST 115 1.14 1.05
TEQZEROS 114 1.13 1.08
TTYPESTR 105 1.04 1.07
TTYPESYM 104 1.03 1.06
TTYPEREL 103 1.02 1.10
TTYPEINT 101 1.00 1.05
------------------------------------------
Completed 1,703,654 = 114