Dimension performance¶
from physipy import Dimension
from physipy.quantity.dimension import parse_str_to_dic
from simparser import new_parse_str_to_dict
We need operations on array-like objects. The solutions are : - a dict - list - numpy array - ordered dict - counter Among these solutions
Most important operators :
- equality check, to check if the dimensions are equal (for Dimension.__eq__)
- addition of values key-wise, when computing the product of 2 dimension (for Dimension.__mul__)
- substration of values key-wise, when computing the division of 2 dimensions (for Dimension.__truediv__)
- multiplication of all values, when computing the exp of a dimension by a scalar (for Dimension.__pow__)
We can rely on the operators, but the actual implementation matters. Exemple for
import operator as op
operators = {
"op.eq":("binary", op.eq),
"op.add":("binary", op.add),
"op.sub":("binary", op.sub),
"op.mul":("binary", op.mul),
}
import time
class Timer():
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
self.end = time.time()
self.secs = self.end - self.start
self.msecs = self.secs * 1000 # millisecs
class Implem():
def __init__(self, name, creator):
self.name = name
self.creator = creator
def __call__(self, *args, **kwargs):
return self.creator(*args, **kwargs)
implemetations = [DimAsDict, DimAsArray, DimAsList]
def bench_dimension_base_data(ns=[3, 4, 5, 6, 7, 8, 10, 15, 20, 50, 100, 1000, 10000]):
# 4 operations to time
# for various number of dimensions
# for all implemetations
# need to store the result of each test
res = []
for implem in implemetations:
for opmeta in operators:
for n in ns:
obj = implem(n)
if opmeta[0] == "binary":
op = opmeta[1]
with Timer() as t:
resop = op(obj, obj)
res_dict = {
"implem":implem.name,
"n":n,
"result":resop,
"time":t.msecs,
}
res.append(res_dict)
import numpy as np
class DimAsListArray():
"""
Benefit the speed of array when computing mul/div, and speed of list equality for keys
"""
def __init__(self, values=np.zeros(3), KEYS=BASEKEYS):
self.dims_keys = KEYS
self.dim_values = values
def __mul__(self, other):
return DimAsListArray(self.dim_values+other.dim_values)
import numpy as np
import collections
"""Goal : return True if 2 vectors of numbers are equal
Inputs :
- vectors are assured to be the same size
- vector values can be int, float, np.numbers, fractions
- the order of the numbers matters (like with dict comparison or ordered dict)
"""
as_dictl = {"A":0, "B":0, "C":0}
as_dictr = {"A":0, "B":0, "C":0}
as_listl = [0, 0, 0]
as_listr = [0, 0, 0]
as_arryl = np.array([0, 0, 0])
as_arryr = np.array([0, 0, 0])
as_odictl = collections.OrderedDict( {"A":0, "B":0, "C":0})
as_odictr = collections.OrderedDict( {"A":0, "B":0, "C":0})
as_counterl = collections.Counter("AAABBBCCC")
as_counterr = collections.Counter("AAABBBCCC")
%timeit as_listl == as_listr
%timeit as_dictl == as_dictr
%timeit as_counterl == as_counterr
%timeit as_odictl == as_odictr
%timeit as_arryl.tolist() == as_arryr.tolist()
%timeit list(as_odictl.values()) == list(as_odictr.values())
%timeit np.array_equal(as_arryl, as_arryr)
%timeit np.all(as_arryl == as_arryr)
import numpy as np
import collections
from operator import add
as_dictl = {"A":0, "B":0, "C":0}
as_dictr = {"A":0, "B":0, "C":0}
as_listl = [0, 0, 0]
as_listr = [0, 0, 0]
as_arryl = np.array([0, 0, 0])
as_arryr = np.array([0, 0, 0])
as_odictl = collections.OrderedDict( {"A":0, "B":0, "C":0})
as_odictr = collections.OrderedDict( {"A":0, "B":0, "C":0})
%timeit [l+r for l,r in zip(as_listl, as_listr)]
%timeit {k:as_dictl[k]+as_dictr[k] for k in (as_dictl.keys() & as_dictr.keys())}
#%timeit as_odictl == as_odictr
#%timeit as_arryl.tolist() == as_arryr.tolist()
#%timeit list(as_odictl.values()) == list(as_odictr.values())
#%timeit np.array_equal(as_arryl, as_arryr)
%timeit as_arryl + as_arryr
%timeit list(map(add, as_listl, as_listr))
import numpy as np
import collections
from operator import mul
as_dictl = {"A":0, "B":0, "C":0}
as_dictr = {"A":0, "B":0, "C":0}
as_listl = [0, 0, 0]
as_listr = [0, 0, 0]
as_arryl = np.array([0, 0, 0])
as_arryr = np.array([0, 0, 0])
as_odictl = collections.OrderedDict( {"A":0, "B":0, "C":0})
as_odictr = collections.OrderedDict( {"A":0, "B":0, "C":0})
%timeit [l*r for l,r in zip(as_listl, as_listr)]
%timeit {k:as_dictl[k]*as_dictr[k] for k in (as_dictl.keys() & as_dictr.keys())}
#%timeit as_odictl == as_odictr
#%timeit as_arryl.tolist() == as_arryr.tolist()
#%timeit list(as_odictl.values()) == list(as_odictr.values())
#%timeit np.array_equal(as_arryl, as_arryr)
%timeit as_arryl * as_arryr
%timeit list(map(mul, as_listl, as_listr))
import numpy as np
import collections
from operator import pow
as_dictl = {"A":1, "B":1, "C":1}
as_dictr = 2
as_listl = [1, 1, 1]
as_listr = 2
as_arryl = np.array([1, 1, 1])
as_arryr = 2
as_odictl = collections.OrderedDict( {"A":1, "B":1, "C":1})
as_odictr = 2
%timeit [l**as_dictr for l in as_listl]
%timeit {k:as_dictl[k]**as_dictr for k in as_dictl.keys()}
%timeit as_arryl ** as_arryr
%timeit list(map(lambda x:x**2, as_listl))