Performance Analysis

Python-enclined scientists do not use any Units of Measures (UoM) checking library with the computation overhead they often induce during execution. Python is a dynamic language, and most tools provide dynamic checking of the UoM, every time a function is called with potentially different parameters and different units of measures.

impunity statically checks the UoM of variables in the code based on annotations and modifies the AST at definition time. We show in the following that impunity is a lot quicker than four existing libraries, chosen among other Python libraries dealing with UoM for their support, regular updates and community.

  • numericalunits uses a complete set of independent base units (meters, kilograms, seconds, coulombs, kelvins) that are defined as randomly-chosen positive floating-point numbers, different for all executions. If units are consistent, the randomness disappears; if not, two executions of the same code return different values. All other units and constants are defined in terms of those. In a dimensionally-correct calculation, the units all cancel out, so the final answer is deterministic, not random. In a dimensionally-incorrect calculations, there will be random factors causing a randomly-varying final answer.

  • astropy is a Python package offering functionalities aimed at astronomers and astrophysicists. It also includes an implementation of the quantity design pattern. astropy also implements a decorator to check calls of functions with quantity parameters.

  • Pint also provides an implementation of the quantity design pattern as a standalone library. It is flexible and provides good integration with other scientific libraries like Pandas (through extension types) or NumPy.

  • Quantities is designed to handle arithmetic and conversions of physical quantities, which have a magnitude, dimensionality specified by various units, and possibly an uncertainty. Quantities builds on the popular NumPy library and is designed to work with NumPy’s standard ufuncs, many of which are already supported.

For each library, two different use-cases are considered based on the example speed function. One with variables annotated with the correct units (meters and seconds), and one with different but commensurable units (meters and hours). In both cases, two NumPy arrays of shape (10000,) are sent as parameters. The computation time over 300 iterations is then averaged. Execution times for both use-cases are displayed here :

_images/impunity_performance.svg

As we can see, the overhead induced by impunity is minimal. This is mainly due to the difference between the dynamic checking of the other libraries and the static analysis done by impunity. By changing the AST directly before execution, impunity limits its overhead to the multiplications added to keep the units coherent between each others. This is also why, when UoM are identical, the overhead is non-existent.