diff options
| author | Hernan <hernan.grecco@gmail.com> | 2020-10-05 14:44:10 -0300 |
|---|---|---|
| committer | Hernan <hernan.grecco@gmail.com> | 2020-10-08 15:16:04 -0300 |
| commit | b6b22f38dccac119920acb6a7b5895da7b310f33 (patch) | |
| tree | 1fbf14d7ed12a46b7b8ab6e1e93ef87650330a9f /benchmarks | |
| parent | 5e59f373ea237a95f22960a2b169c3a756a264c9 (diff) | |
| download | pint-b6b22f38dccac119920acb6a7b5895da7b310f33.tar.gz | |
Implements a first benchmark suite.
The benchmark is based on airspeed velocity (asv). Benchmarks are organized with double digits numbers
to create a nice, sorted
00-09: Benchmarks that do not require a registry created during setup
10-19: Benchmarks calling functions directly from the registry
20-29: Benchmarks involving Units and Quantity objects (with scalar values)
30-39: Benchmarks involving Quantity objects (with array values)
Briefly, you can run the the benchmark calling:
$ asv run
or if you want to compare certain commits/branches:
$ asv run master..mybranch
For convenience, we include a list of hashes of all pint versions:
$ asv run HASHFILE:benchmarks/hashes.txt
--
After running the benchmark, run:
$ asv publish
$ asv preview
To get a nice readable output.
More information on: https://asv.readthedocs.io/en/stable/
Diffstat (limited to 'benchmarks')
| -rw-r--r-- | benchmarks/00_common.py | 2 | ||||
| -rw-r--r-- | benchmarks/01_registry_creation.py | 10 | ||||
| -rw-r--r-- | benchmarks/10_registry.py | 101 | ||||
| -rw-r--r-- | benchmarks/20_quantity.py | 56 | ||||
| -rw-r--r-- | benchmarks/30_numpy.py | 97 | ||||
| -rw-r--r-- | benchmarks/__init__.py | 0 | ||||
| -rw-r--r-- | benchmarks/hashes.txt | 32 | ||||
| -rw-r--r-- | benchmarks/util.py | 38 |
8 files changed, 336 insertions, 0 deletions
diff --git a/benchmarks/00_common.py b/benchmarks/00_common.py new file mode 100644 index 0000000..4444d5d --- /dev/null +++ b/benchmarks/00_common.py @@ -0,0 +1,2 @@ +def time_import(): + import pint diff --git a/benchmarks/01_registry_creation.py b/benchmarks/01_registry_creation.py new file mode 100644 index 0000000..e555585 --- /dev/null +++ b/benchmarks/01_registry_creation.py @@ -0,0 +1,10 @@ +import pint + +from . import util + + +def time_create_registry(args): + pint.UnitRegistry(*args) + + +time_create_registry.params = [[(None,), tuple(), (util.get_tiny_def(),)]] diff --git a/benchmarks/10_registry.py b/benchmarks/10_registry.py new file mode 100644 index 0000000..d95a53f --- /dev/null +++ b/benchmarks/10_registry.py @@ -0,0 +1,101 @@ +import pint + +from . import util + +units = ("meter", "kilometer", "second", "minute", "angstrom") + +other_units = ("meter", "angstrom", "kilometer/second", "angstrom/minute") + +all_values = ("int", "float", "complex") + +ureg = None +data = {} + + +def setup(*args): + + global ureg, data + + data["int"] = 1 + data["float"] = 1.0 + data["complex"] = complex(1, 2) + + ureg = pint.UnitRegistry(util.get_tiny_def()) + + +def my_setup(*args): + global data + setup(*args) + for unit in units + other_units: + data["uc_%s" % unit] = pint.registry.to_units_container(unit, ureg) + + +def time_build_cache(): + ureg._build_cache() + + +def time_getattr(key): + getattr(ureg, key) + + +time_getattr.params = units + + +def time_getitem(key): + ureg[key] + + +time_getitem.params = units + + +def time_parse_unit_name(key): + ureg.parse_unit_name(key) + + +time_parse_unit_name.params = units + + +def time_parse_units(key): + ureg.parse_units(key) + + +time_parse_units.params = units + + +def time_parse_expression(key): + ureg.parse_expression("1.0 " + key) + + +time_parse_expression.params = units + + +def time_base_units(unit): + ureg.get_base_units(unit) + + +time_base_units.params = other_units + + +def time_to_units_container_registry(unit): + pint.registry.to_units_container(unit, ureg) + + +time_to_units_container_registry.params = other_units + + +def time_to_units_container_detached(unit): + pint.registry.to_units_container(unit, ureg) + + +time_to_units_container_detached.params = other_units + + +def time_convert_from_uc(key): + src, dst = key + ureg._convert(1.0, data[src], data[dst]) + + +time_convert_from_uc.setup = my_setup +time_convert_from_uc.params = [ + (("uc_meter", "uc_kilometer"), ("uc_kilometer/second", "uc_angstrom/minute")) +] diff --git a/benchmarks/20_quantity.py b/benchmarks/20_quantity.py new file mode 100644 index 0000000..5f6dd41 --- /dev/null +++ b/benchmarks/20_quantity.py @@ -0,0 +1,56 @@ +import itertools as it +import operator + +import pint + +from . import util + +units = ("meter", "kilometer", "second", "minute", "angstrom") +all_values = ("int", "float", "complex") +all_values_q = tuple( + "%s_%s" % (a, b) for a, b in it.product(all_values, ("meter", "kilometer")) +) + +op1 = (operator.neg, operator.truth) +op2_cmp = (operator.eq,) # operator.lt) +op2_math = (operator.add, operator.sub, operator.mul, operator.truediv) + +ureg = None +data = {} + + +def setup(*args): + + global ureg, data + + data["int"] = 1 + data["float"] = 1.0 + data["complex"] = complex(1, 2) + + ureg = pint.UnitRegistry(util.get_tiny_def()) + + for key in all_values: + data[key + "_meter"] = data[key] * ureg.meter + data[key + "_kilometer"] = data[key] * ureg.kilometer + + +def time_build_by_mul(key): + data[key] * ureg.meter + + +time_build_by_mul.params = all_values + + +def time_op1(key, op): + op(data[key]) + + +time_op1.params = [all_values_q, op1] + + +def time_op2(keys, op): + key1, key2 = keys + op(data[key1], data[key2]) + + +time_op2.params = [tuple(it.product(all_values_q, all_values_q)), op2_math + op2_cmp] diff --git a/benchmarks/30_numpy.py b/benchmarks/30_numpy.py new file mode 100644 index 0000000..ec83833 --- /dev/null +++ b/benchmarks/30_numpy.py @@ -0,0 +1,97 @@ +import itertools as it +import operator + +import numpy as np + +import pint + +from . import util + +lengths = ("short", "mid") +all_values = tuple( + "%s_%s" % (a, b) for a, b in it.product(lengths, ("list", "tuple", "array")) +) +all_arrays = ("short_array", "mid_array") +units = ("meter", "kilometer") +all_arrays_q = tuple("%s_%s" % (a, b) for a, b in it.product(all_arrays, units)) + +ureg = None +data = {} +op1 = (operator.neg,) # operator.truth, +op2_cmp = (operator.eq, operator.lt) +op2_math = (operator.add, operator.sub, operator.mul, operator.truediv) +numpy_op2_cmp = (np.equal, np.less) +numpy_op2_math = (np.add, np.subtract, np.multiply, np.true_divide) + + +def float_range(n): + return (float(x) for x in range(1, n + 1)) + + +def setup(*args): + + global ureg, data + short = list(float_range(3)) + mid = list(float_range(1_000)) + + data["short_list"] = short + data["short_tuple"] = tuple(short) + data["short_array"] = np.asarray(short) + data["mid_list"] = mid + data["mid_tuple"] = tuple(mid) + data["mid_array"] = np.asarray(mid) + + ureg = pint.UnitRegistry(util.get_tiny_def()) + + for key in all_arrays: + data[key + "_meter"] = data[key] * ureg.meter + data[key + "_kilometer"] = data[key] * ureg.kilometer + + +def time_finding_meter_getattr(): + ureg.meter + + +def time_finding_meter_getitem(): + ureg["meter"] + + +def time_base_units(unit): + ureg.get_base_units(unit) + + +time_base_units.params = ["meter", "angstrom", "meter/second", "angstrom/minute"] + + +def time_build_by_mul(key): + data[key] * ureg.meter + + +time_build_by_mul.params = all_arrays + + +def time_op1(key, op): + op(data[key]) + + +time_op1.params = [all_arrays_q, op1 + (np.sqrt, np.square)] + + +def time_op2(keys, op): + key1, key2 = keys + op(data[key1], data[key2]) + + +time_op2.params = [ + ( + ("short_array_meter", "short_array_meter"), + ("short_array_meter", "short_array_kilometer"), + ("short_array_kilometer", "short_array_meter"), + ("short_array_kilometer", "short_array_kilometer"), + ("mid_array_meter", "mid_array_meter"), + ("mid_array_meter", "mid_array_kilometer"), + ("mid_array_kilometer", "mid_array_meter"), + ("mid_array_kilometer", "mid_array_kilometer"), + ), + op2_math + op2_cmp + numpy_op2_math + numpy_op2_cmp, +] diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/benchmarks/__init__.py diff --git a/benchmarks/hashes.txt b/benchmarks/hashes.txt new file mode 100644 index 0000000..473130b --- /dev/null +++ b/benchmarks/hashes.txt @@ -0,0 +1,32 @@ +04468ad216555cab2b50dbae62b57f56bf694cc3 +a964aebfb904d5ac4cb2645478f38189b27ad97a +7f77dabbfcd1be8b5943cbb6ee3b049c66d337f6 +d78cc94a9538aeb91b30494bdcde1348cab0e2f6 +040b01283470b95d23a244eb1a791dfd189502c6 +5ca84aca6002ec1550417bf791b3f8cc9e551818 +2dc133ef61baf3f6b2b54814cbeb3299282ee794 +1d3f26bfcabab7751bd324d1fd48825667c2e949 +126e00f691007ff71e6a2c327b19f92d8a478adb +2c0c4ee67f732b0d1b7530e8363b15c57b936b97 +619b95ee13f82560c3cd596095bcd606ba0277ae +6e18639b3db4121322e0fc7009df463b8dc7ee9f +fe0a64b270dbde0946fdcb0819aad178d42f77e6 +6aea7d4aaf424e2a514c004f99b271ecfb446237 +c48c441ec6b8919f104edd6affb57b69aa275a38 +7d9837ead056af2e36009a0b0ed8d1a9e9bf3947 +e7e7de5ca2e1c19963be8a918369fb19186f9a73 +f65bebb6930fdd5ec891a905c30489a52add05f6 +a171cdfbab64903ae67d7461b0904f350191ee29 +7196ae6794a5f7b3ab0a48e880f1797a218e59de +5ee3ff950709ab356d7349d6b56818b0c5fe624b +697834d17d6fb5bb5d0adf945a5d5f5d187506a1 +2b296e79f0260b8d547af8d078178f079d90a3d9 +a91762071e3cecc8d995c993a3175f84ed9ec804 +82b2c2f97b3f929568a07850de4f75b0d16f3c56 +3d713cf920c1f164c1c3c2fcfab96956467b0d64 +eed85601c8bdf0829ed256cdf2af9982bc9ed5a2 +4e6dbff740292ae57230686ad4417e46d63e171c +222a1c89e9ce5c24debc749558cf5eb3b231f89a +85603e644e9ba004188ef79e499b9a40557b446c +9a05e600275c592451bda9287205fe0e99a87bb3 +6b0b531d5311ab0f61aefd3e76a8dec9144d6b81
\ No newline at end of file diff --git a/benchmarks/util.py b/benchmarks/util.py new file mode 100644 index 0000000..4e72048 --- /dev/null +++ b/benchmarks/util.py @@ -0,0 +1,38 @@ +import io + +SMALL_VEC_LEN = 3 +MID_VEC_LEN = 1_000 +LARGE_VEC_LEN = 1_000_000 + +TINY_DEF = """ +yocto- = 1e-24 = y- +zepto- = 1e-21 = z- +atto- = 1e-18 = a- +femto- = 1e-15 = f- +pico- = 1e-12 = p- +nano- = 1e-9 = n- +micro- = 1e-6 = µ- = u- +milli- = 1e-3 = m- +centi- = 1e-2 = c- +deci- = 1e-1 = d- +deca- = 1e+1 = da- = deka- +hecto- = 1e2 = h- +kilo- = 1e3 = k- +mega- = 1e6 = M- +giga- = 1e9 = G- +tera- = 1e12 = T- +peta- = 1e15 = P- +exa- = 1e18 = E- +zetta- = 1e21 = Z- +yotta- = 1e24 = Y- + +meter = [length] = m = metre +second = [time] = s = sec + +angstrom = 1e-10 * meter = Å = ångström = Å +minute = 60 * second = min +""" + + +def get_tiny_def(): + return io.StringIO(TINY_DEF) |
