summaryrefslogtreecommitdiff
path: root/benchmarks
diff options
context:
space:
mode:
authorHernan <hernan.grecco@gmail.com>2020-10-05 14:44:10 -0300
committerHernan <hernan.grecco@gmail.com>2020-10-08 15:16:04 -0300
commitb6b22f38dccac119920acb6a7b5895da7b310f33 (patch)
tree1fbf14d7ed12a46b7b8ab6e1e93ef87650330a9f /benchmarks
parent5e59f373ea237a95f22960a2b169c3a756a264c9 (diff)
downloadpint-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.py2
-rw-r--r--benchmarks/01_registry_creation.py10
-rw-r--r--benchmarks/10_registry.py101
-rw-r--r--benchmarks/20_quantity.py56
-rw-r--r--benchmarks/30_numpy.py97
-rw-r--r--benchmarks/__init__.py0
-rw-r--r--benchmarks/hashes.txt32
-rw-r--r--benchmarks/util.py38
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)