RSS Feed

Lisp Project of the Day

trivial-benchmark

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

trivial-benchmarkperformancetrivial

Documentation๐Ÿ˜€
Docstrings๐Ÿ˜€
Tests ๐Ÿฅบ
Examples๐Ÿ˜€
RepositoryActivity๐Ÿคจ
CI ๐Ÿฅบ

Some time ago I've reviewed the the-cost-of-nothing library which allowed you to check the performance of the form execution. Trivial-benchmark does a similar job but has a few pros and cons.

The main con is that you have to give it a number of iterations manually, but the pro is that the library provides a way more statistics:

POFTHEDAY> (trivial-benchmark:with-timing (1000000)
             (format nil "Symbol is: ~S" :foo))

-                SAMPLES  TOTAL      MINIMUM   MAXIMUM   MEDIAN    AVERAGE    DEVIATION  
REAL-TIME        1000000  3.78       0         0.169     0         0.000004   0.000207   
RUN-TIME         1000000  3.734      0         0.132     0         0.000004   0.000179   
USER-RUN-TIME    1000000  2.332375   0.000001  0.061505  0.000002  0.000002   0.00011    
SYSTEM-RUN-TIME  1000000  1.398129   0.000001  0.070875  0.000001  0.000001   0.000072   
PAGE-FAULTS      1000000  0          0         0         0         0          0.0        
GC-RUN-TIME      1000000  0.436      0         0.132     0         0.0        0.000168   
BYTES-CONSED     1000000  592388352  0         130976    0         592.38837  4354.098   
EVAL-CALLS       1000000  0          0         0         0         0          0.0

Another cool feature is the ability to define more custom metrics.

Here is a practical example. We'll measure a number of SQL queries made during form execution:

;; These are owr SQL driver simulation:
POFTHEDAY> (defparameter *num-queries* 0)

POFTHEDAY> (defun execute (query)
             "A fake SQL driver"
             (declare (ignorable query))
             (incf *num-queries*))

;; The application code:
POFTHEDAY> (defun the-view ()
             (execute "SELECT some FROM data")
             (loop repeat 5
                   do (execute "SELECT some FROM other_data")))

;; Metric definition is very simple. You just provide a code
;; which returns an absolute value:
POFTHEDAY> (trivial-benchmark:define-delta-metric sql-queries
             *num-queries*)

;; Pay attention to the last line of the report:
POFTHEDAY> (trivial-benchmark:with-timing (100)
             (the-view))
-                SAMPLES  TOTAL     MINIMUM   MAXIMUM   MEDIAN    AVERAGE   DEVIATION  
REAL-TIME        100      0         0         0         0         0         0.0        
RUN-TIME         100      0         0         0         0         0         0.0        
USER-RUN-TIME    100      0.000308  0.000001  0.00012   0.000002  0.000003  0.000012   
SYSTEM-RUN-TIME  100      0.000117  0.000001  0.000002  0.000001  0.000001  0.0        
PAGE-FAULTS      100      0         0         0         0         0         0.0        
GC-RUN-TIME      100      0         0         0         0         0         0.0        
BYTES-CONSED     100      98240     0         65536     0         982.4     7258.1045  
EVAL-CALLS       100      0         0         0         0         0         0.0        
SQL-QUERIES      100      600       6         6         6         6         0.0

The trivial-benchmark is not as accurate as the-cost-of-nothing because it does not count the overhead, but overhead can be significant because trivial-benchmark uses generic functions.

Also when sampling, the trivial-benchmark executes the form only once. That is why the measurements for a very fast code will be even more inaccurate.

Another interesting feature is the ability to define benchmark suites to measure performance regression of some parts of your code. I won't show you an example of such a suite. Just go and read nice documentation, written by @Shinmera:

https://github.com/Shinmera/trivial-benchmark#benchmark-suites


Brought to you by 40Ants under Creative Commons License