`%timeit`

and `%time`

magic commands usually serve my purpose. Their use is quite simple. The `%time`

returns the elapsed time for the expression that follows. The `%timeit`

magic command allows for control over how many times should the expression be executed in a loop, how many loops, precision of the result, among others. In short, it's closer in functionality to Python's *timeit* module.

```
In [1]:
```%time a = [i**2 for i in range(10000)]

```
```

```
In [2]:
```%timeit a = [i**2 for i in range(10000)]

```
```

*timeit* module. I like *Matlab*'s names for their stopwatch commands, so I based myself on them (I think *tac* is a better sound *toc* but that's another matter).

```
In [23]:
```from timeit import default_timer as timer
class Timer():
def __init__(self, ID = None):
self.start = None
self.end = None
self.elapsed = 0
def tic(self):
self.start = timer()
def tac(self):
self.end = timer()
self.elapsed += self.end - self.start
return self.elapsed
def reset(self):
self.elapsed = 0
t = Timer()
t.tic()
a = [i**2 for i in range(10000)]
t.tac()

```
Out[23]:
```

```
In [32]:
```def wrapper_add(fn, *args, **kwargs):
t = Timer()
t.tic()
returnvals = fn(*args, **kwargs)
t.tac()
return returnvals, t.elapsed
add = lambda x, y: x + y
wrapper_add(add, 1, 1)

```
Out[32]:
```

```
In [ ]:
```class Timer():
# ... other methods ...
def wrap_function(self, fn):
def timed_fn(*args,**kwargs):
self.tic()
returnvals = fn(*args,**kwargs)
self.tac()
return returnvals
return timed_fn

This method is taking in a function then creates a wrapper function like the one in the last example and returns it. It's that simple.

I can create a normal timer like in the above examples and then I can wrap a function with that specific timer. Whenever that function is executed it increments the timer with the elapsed time.

```
In [35]:
```add = lambda x, y: x + y
t = Timer()
print t.elapsed
add_t = t.wrap_function(add)
add_t(2,2)
print t.elapsed
add_t = t.wrap_function(add)
add_t(2,2)
print t.elapsed

```
```

```
In [127]:
```import numpy as np
class Dummy:
def __init__(self, x, y):
self.x = np.random.random(x)
self.y = np.random.random(y)
def _add(self):
self.total = self.x + self.y
return self.total
t1 = Timer()
t2 = Timer()
d = Dummy(10000000, 10000000)
t1.tic()
d._add()
t1.tac()
print d.total.sum(), t1.elapsed * 1000
d._add = t2.wrap_function(d._add)
d._add()
print d.total.sum(), t2.elapsed * 1000

```
```

*read-only* then it's no play, as can be seen when I tried this on a NumPy array method.

```
In [130]:
```import numpy as np
t = Timer()
arr = np.random.random(100000)
arr.sort = t.wrap_function(arr.argsort)

```
```