summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Dartiailh <marul@laposte.net>2014-10-17 19:46:45 +0200
committerMatthieu Dartiailh <marul@laposte.net>2014-10-17 19:46:45 +0200
commit082a338cfb6c86cb565f0ae788d2d60a03f8ad2f (patch)
tree79f14d90dd10896e0aef0e1311127753fa15a2f4
parentb29ed165b82df4609545c586caf6a35968133274 (diff)
downloadpint-082a338cfb6c86cb565f0ae788d2d60a03f8ad2f.tar.gz
Add caching for get_dimensionality for non base units. Add unit parser cache to make q1.to('mV') as fast as q1.to(q2.units)
-rw-r--r--pint/unit.py28
1 files changed, 20 insertions, 8 deletions
diff --git a/pint/unit.py b/pint/unit.py
index 1431432..5c8ee6a 100644
--- a/pint/unit.py
+++ b/pint/unit.py
@@ -509,6 +509,9 @@ class UnitRegistry(object):
#: Maps dimensionality (_freeze(UnitsContainer)) to Units (_freeze(UnitsContainer))
self._dimensionality_cache = TransformDict(_freeze)
+ #: Cache the unit name associated to user input. ('mV' -> 'millivolt')
+ self._parse_unit_cache = dict()
+
#: When performing a multiplication of units, interpret
#: non-multiplicative units as their *delta* counterparts.
self.default_as_delta = default_as_delta
@@ -906,6 +909,8 @@ class UnitRegistry(object):
if '[]' in dims:
del dims['[]']
+ self._dimensionality_cache[input_units] = copy.copy(dims)
+
return dims
def _get_dimensionality_recurse(self, ref, exp, accumulator):
@@ -1137,9 +1142,10 @@ class UnitRegistry(object):
"""Parse a unit to identify prefix, unit name and suffix
by walking the list of prefix and suffix.
"""
-
- for suffix, prefix in itertools.product(self._suffixes.keys(), self._prefixes.keys()):
- if unit_name.startswith(prefix) and unit_name.endswith(suffix):
+ stw = unit_name.startswith
+ edw = unit_name.endswith
+ for suffix, prefix in itertools.product(self._suffixes, self._prefixes):
+ if stw(prefix) and edw(suffix):
name = unit_name[len(prefix):]
if suffix:
name = name[:-len(suffix)]
@@ -1147,13 +1153,13 @@ class UnitRegistry(object):
continue
if case_sensitive:
if name in self._units:
- yield (self._prefixes[prefix].name,
- self._units[name].name,
+ yield (self._prefixes[prefix]._name,
+ self._units[name]._name,
self._suffixes[suffix])
else:
for real_name in self._units_casei.get(name.lower(), ()):
- yield (self._prefixes[prefix].name,
- self._units[real_name].name,
+ yield (self._prefixes[prefix]._name,
+ self._units[real_name]._name,
self._suffixes[suffix])
def parse_units(self, input_string, as_delta=None):
@@ -1169,6 +1175,9 @@ class UnitRegistry(object):
:class:`pint.UndefinedUnitError` if a unit is not in the registry
:class:`ValueError` if the expression is invalid.
"""
+ if input_string in self._parse_unit_cache:
+ return self._parse_unit_cache[input_string]
+
if as_delta is None:
as_delta = self.default_as_delta
@@ -1181,8 +1190,9 @@ class UnitRegistry(object):
ret = UnitsContainer()
many = len(units) > 1
- for name, value in units.items():
+ for name in units:
cname = self.get_name(name)
+ value = units[name]
if not cname:
continue
if as_delta and (many or (not many and value != 1)):
@@ -1191,6 +1201,8 @@ class UnitRegistry(object):
cname = 'delta_' + cname
ret[cname] = value
+ self._parse_unit_cache[input_string] = ret
+
return ret
def parse_expression(self, input_string, case_sensitive=True, **values):