Skip to content
Snippets Groups Projects
Commit 2bbc5934 authored by mads's avatar mads
Browse files

timing and caching functions/decorators

parent b0579257
No related branches found
No related tags found
No related merge requests found
......@@ -21,7 +21,7 @@ General Time Series Data Format, a binary hdf5 data format for storing time seri
### [wind](wetb/wind)
- [shear](wetb/wind/shear.py): Calculate and fit wind shear
### [FAST](wetb/fast)
### [fast](wetb/fast)
Tools for working with NREL's FAST code (An aeroelastic computer-aided engineering (CAE) tool for horizontal axis wind turbines)
- [fast_io](wetb/fast/fast_io.py): Read binary and ascii result files
......
'''
Created on 07/02/2014
@author: MMPE
'''
import inspect
def set_cache_property(obj, name, get_func, set_func=None):
"""Create a cached property
Parameters
----------
obj : object
Class to add property to
name : str
Name of property
get_func : func
Getter function
set_func : func, optional
Setter function
Examples
--------
>>> class Example(object):
>>> def __init__(self):
>>> set_cache_property(self, "test", self.slow_function)
>>>
>>> e = Example()
>>> e.test # Call, store and return result of e.slow_function
>>> e.test # Return stored result of e.slow_function
"""
_name = "_" + name
setattr(obj, _name, None)
def get(self):
if getattr(obj, _name) is None:
setattr(obj, _name, get_func())
return getattr(obj, _name)
p = property(lambda self:get(self), set_func)
return setattr(obj.__class__, name, p)
def cache_function(f):
"""Cache function decorator
Example:
>>> class Example(object):
>>> @cache_function
>>> def slow_function(self):
>>> # calculate slow result
>>> return 1
>>>
>>> e = Example()
>>> e.slow_function() # Call, store and return result of e.slow_function
>>> e.slow_function() # Return stored result of e.slow_function
"""
def wrap(*args, **kwargs):
self = args[0]
name = "_" + f.__name__
if not hasattr(self, name) or getattr(self, name) is None or kwargs.get("reload", False):
try:
del kwargs['reload']
except KeyError:
pass
# ======HERE============
setattr(self, name, f(*args, **kwargs))
# ======================
if not hasattr(self, "cache_attr_lst"):
self.cache_attr_lst = set()
def clear_cache():
for attr in self.cache_attr_lst:
delattr(self, attr)
self.cache_attr_lst = set()
self.clear_cache = clear_cache
self.cache_attr_lst.add(name)
return getattr(self, name)
if 'reload' in inspect.getargspec(f)[0]:
raise AttributeError("Functions decorated with cache_function are not allowed to take a parameter called 'reload'")
return wrap
'''
Created on 08/11/2013
@author: mmpe
'''
import multiprocessing
import time
import unittest
from wetb.functions.timing import get_time
from wetb.functions.caching import cache_function, set_cache_property
class Example(object):
def __init__(self, *args, **kwargs):
object.__init__(self, *args, **kwargs)
set_cache_property(self, "test", self.slow_function)
set_cache_property(self, 'pool', lambda : multiprocessing.Pool(20))
def slow_function(self):
time.sleep(1)
return 1
@cache_function
def test_cache_function(self):
return self.slow_function()
@get_time
def prop(self, prop):
return getattr(self, prop)
def f(x):
return x ** 2
class TestCacheProperty(unittest.TestCase):
def setUp(self):
pass
def testcache_property_test(self):
e = Example()
self.assertAlmostEqual(e.prop("test")[1], 1, 2)
self.assertAlmostEqual(e.prop("test")[1], 0, 2)
def testcache_property_pool(self):
e = Example()
print (e.prop("pool"))
self.assertAlmostEqual(e.prop("pool")[1], 0, places=4)
print (get_time(e.pool.map)(f, range(10)))
def test_cache_function(self):
e = Example()
self.assertAlmostEqual(get_time(e.test_cache_function)()[1], 1, places=2)
self.assertAlmostEqual(get_time(e.test_cache_function)()[1], 0, places=2)
self.assertAlmostEqual(get_time(e.test_cache_function)(reload=True)[1], 1, places=2)
self.assertAlmostEqual(get_time(e.test_cache_function)()[1], 0, places=2)
e.clear_cache()
self.assertAlmostEqual(get_time(e.test_cache_function)()[1], 1, places=2)
if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
from six import exec_
import time
import inspect
def get_time(f):
def wrap(*args, **kwargs):
t = time.clock()
res = f(*args, **kwargs)
return res, time.clock() - t
w = wrap
w.__name__ = f.__name__
return w
def print_time(f):
def wrap(*args, **kwargs):
t = time.time()
res = f(*args, **kwargs)
print ("%-12s\t%.3fs" % (f.__name__, time.time() - t))
return res
w = wrap
w.__name__ = f.__name__
return w
cum_time = {}
def print_cum_time(f):
if f not in cum_time:
cum_time[f] = (0, 0)
def wrap(*args, **kwargs):
t = time.time()
res = f(*args, **kwargs)
ct = cum_time[f][1] + time.time() - t
n = cum_time[f][0] + 1
cum_time[f] = (n, ct)
print ("%-12s\t%.4d calls, %03fs, %fs pr. call'" % (f.__name__, n, ct, ct / n))
return res
w = wrap
w.__name__ = f.__name__
return w
def print_line_time(f):
def wrap(*args, **kwargs):
arg_names, varargs, varkw, defaults = inspect.getargspec(f)
kwargs[varargs] = args[len(arg_names):]
kwargs[varkw] = {}
for k, v in kwargs.items():
if k not in tuple(arg_names) + (varargs, varkw):
kwargs.pop(k)
kwargs[varkw][k] = v
if defaults:
kwargs.update(dict(zip(arg_names[::-1], defaults[::-1])))
kwargs.update(dict(zip(arg_names, args)))
lines = inspect.getsourcelines(f)[0][2:]
tcum = time.clock()
locals = kwargs
gl = f.__globals__
for l in lines:
tline = time.clock()
exec(l.strip(), locals, gl) #res = f(*args, **kwargs)
print ("%.3fs\t%.3fs\t%s" % (time.clock() - tline, time.clock() - tcum, l.strip()))
w = wrap
w.__name__ = f.__name__
return w
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment