source: branches/decorate/timer.py @ 855

Revision 855, 5.8 KB checked in by mmckerns, 5 months ago (diff)

updated copyright to 2016

Line 
1#!/usr/bin/env python
2#
3# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4# Copyright (c) 2012-2016 California Institute of Technology.
5# License: 3-clause BSD.  The full license text is available at:
6#  - http://mmckerns.github.io/project/mystic/browser/mystic/LICENSE
7
8def timed(verbose=True):
9    def dec(f):
10        """decorator for timing a function"""
11        from time import time as now
12        __time = [True, None]
13        if not verbose: __time[0] = False
14        def time(stamp=False):
15            if not stamp: return __time[-1]
16            import datetime
17            return datetime.timedelta(seconds=__time[-1])
18        def __verbose(on=True):
19            __time[0] = bool(on)
20        def func(*args, **kwds):
21            t = now()
22            res = f(*args, **kwds)
23            __time[-1] = now() - t
24            if __time[0]:
25                print "Timed: %s" % __time[-1]
26            return res
27        func.time = time
28        func.verbose = __verbose
29        return func
30    return dec
31
32
33class Timer(object):
34    """
35Instances of timer objects that can be passed as timers.
36Typically, a timer is attached to a monitor and is called
37when the monitor is called.
38
39example usage...
40    >>> timer = Timer()
41    >>> timer.stamp = False
42    >>> timer()
43    >>> timer._t
44    51.91421914100647
45    >>> timer()
46    >>> timer._t
47    74.009551048278809
48    >>> timer.t
49    [51.91421914100647, 74.009551048278809]
50    >>> timer.stamp = True
51    >>> print timer._t
52    0:01:14.009551
53    >>> print timer.t0
54    2012-10-15 13:00:53.758812
55    """
56    def __init__(self, **kwds):
57        self.__on = kwds.get('on', False)
58        self.__off = 0
59        self.__t = []
60        self.__t0 = [self.__now()]
61        self.__stamp = kwds.get('stamp', True)
62        self.__lazy = kwds.get('lazy', True)
63    def __call__(self):
64        if self.__on or self.__lazy:
65            self.__on = True
66            self.__t.extend(self.__deadtime())
67            self.__t.append(self.__now())
68            self.__off = 0
69        else:
70            self.__off += 1
71    def __get_lazy(self):
72        return self.__lazy
73    def __set_lazy(self, ind):
74        """if True, 'call' will turn timer on"""
75        self.__lazy = bool(ind)
76    def __get_stamp(self):
77        return self.__stamp
78    def __set_stamp(self, ind):
79        """if True, _t & t0 return datetime object"""
80        self.__stamp = bool(ind)
81    def __get_on(self):
82        return self.__on
83    def __set_on(self, ind):
84        """if False, record 'nan' instead of a time"""
85        self.__on = bool(ind)
86    def __toggle(self):
87        """toggle the timer on/off"""
88        self.__on = not self.__on
89    def __reset(self):
90        """reset t0 to now"""
91        self.__t0.append(self.__now())
92        #XXX: should reset to original kwds settings? (on, lazy, ...)
93    def __get_t0(self):
94        t = self.__t0[-1]
95        if not self.__stamp: return t
96        import datetime
97        return datetime.datetime.fromtimestamp(t)
98    def __set_t0(self, t): #XXX: allow setting t0 ?
99        self.__t0.append(t)
100    def __first(self):
101        """get all t0 as a list"""
102        return self.__t0
103    def __now(self):
104        from time import time as now
105        return now() 
106    def __deadtime(self):
107        from numpy import NaN
108        return [NaN] * self.__off
109    def __get_t(self):
110        from numpy import array
111        return list(array(self.__t + self.__deadtime()) - self.__t0[-1])
112    def __last(self):
113        """just get the last t, instead of all t"""
114        if not self.__t: return None # require a 'call'
115        t = self.__t[-1] - self.__t0[-1]
116        if t < 0.0: return None  # require a 'call' after a 'reset'
117        if not self.__stamp: return t
118        import datetime
119        return datetime.timedelta(seconds=t)
120    on = property(__get_on, __set_on)
121    toggle = property(__toggle)
122    reset = property(__reset)
123    _t0 = property(__first) # [t0, ...]
124    t0 = property(__get_t0,__set_t0) # t0
125    _t = property(__last) # t
126    t = property(__get_t) # [t, ...]
127    stamp = property(__get_stamp, __set_stamp)
128    lazy = property(__get_lazy, __set_lazy)
129
130
131from mystic.monitors import Monitor
132class TimedMonitor(Monitor):
133    """A timed version of the basic Monitor.
134
135Every time the monitor is called, the time is also logged.
136Timer is configurable through 'monitor.timer'.
137    """
138    def __init__(self, **kwds):#, all=True):
139        timed = kwds.pop('timed', False)
140       #called = kwds.pop('lazy', True)
141       #stamp = kwds.pop('stamp', True)
142        super(TimedMonitor,self).__init__(**kwds)
143        self.timer = Timer(on=timed)#,lazy=called,stamp=stamp)
144        return
145
146    def __call__(self, x, y, id=None, **kwds):#, best=0):
147        self.timer()
148        super(TimedMonitor,self).__call__(x, y, id, **kwds)
149        return
150
151    pass
152
153
154if __name__ == '__main__':
155    monitor = TimedMonitor()
156    monitor.timer.lazy = False
157    monitor([1],1)
158    monitor.timer.on = True
159    monitor([2],2)
160    monitor([3],3)
161    monitor.timer.toggle
162    print "x: %s" % monitor.x
163    print "y: %s" % monitor.y
164    print "t: %s" % monitor.timer.t
165    print "t0: %s" % monitor.timer.t0
166    monitor.timer.stamp = False
167    print "Ran: %s seconds" % monitor.timer._t
168    monitor.timer.stamp = True
169    monitor.timer.reset
170    monitor([4],4)
171    print "x: %s" % monitor.x
172    print "y: %s" % monitor.y
173    print "t: %s" % monitor.timer.t
174    print "t0: %s" % monitor.timer.t0
175    monitor.timer.stamp = False
176    print "Ran: %s seconds" % monitor.timer._t
177    monitor.timer.stamp = True
178    monitor.timer.toggle
179    monitor([5],5)
180    print "x: %s" % monitor.x
181    print "y: %s" % monitor.y
182    print "t: %s" % monitor.timer.t
183    print "t0: %s" % monitor.timer.t0
184    monitor.timer.stamp = False
185    print "Ran: %s seconds" % monitor.timer._t
186    monitor.timer.stamp = True
187    print "Completed: %s" % (monitor.timer._t + monitor.timer.t0)
188
189# EOF
Note: See TracBrowser for help on using the repository browser.