Eugeny/ajenti — pull request #337 by kstep (2014-04-03 14:03:10+00:00)
Title: use datetime.timedelta to format times

I know, this is controversial optimization, but given `str_timedelta()` function is used quite often in templates in `bindtransform` attribute, its call time can add up to relatively large numbers.

I did some testing with current `str_timedelta()` implementation, my own custom implementation and `str(timedelta(0, x))`:

```python
# -*- encoding: utf-8 -*-
from datetime import timedelta

def measure(times=1000000):
def decorator(func):
def wrapper(*args, **kwargs):
from time import time
start = time()
try:
for _ in xrange(0, times):
result = func(*args, **kwargs)
return result

finally:
dt = time() - start
mt = dt / times
print('%s: %0.2f s / %d = %0.4f μs' % (func.__name__, dt, times, mt*1000000))
return wrapper
return decorator

@measure()
def str_timedelta(s):
"""
Formats a time delta (i.e., "5 days, 5:06:07")
"""
d60 = lambda x: ('0' if (x % 60) < 10 else '') + str(x % 60)
s = int(s)
r = '%s:%s:%s' % (d60(s / 3600 % 24), d60(s / 60), d60(s))
s /= 3600 * 24
if s > 0:
r = '%i days, ' % s + r
return r

@measure()
def str_timedelta1(s):
divs = (60, 60, 24)
parts = []
for d in divs:
s, p = divmod(s, d)
parts.append(p)
parts.append(s)

parts.reverse()
return '%i days, %02d:%02d:%02d' % tuple(parts)

@measure()
def str_timedelta2(s):
d = timedelta(0, s)
return str(d)

ts = 86400*3 + 7*3600 + 5*60 + 4
print str_timedelta(ts)
print str_timedelta1(ts)
print str_timedelta2(ts)
```

The results are:

```
str_timedelta: 3.25 s / 1000000 = 3.2492 μs
3 days, 07:05:04
str_timedelta1: 4.11 s / 1000000 = 4.1149 μs
3 days, 07:05:04
str_timedelta2: 1.55 s / 1000000 = 1.5494 μs
3 days, 7:05:04
```

I.e. `timedelta` outperforms current implementation about two times! Besides it prints singular form of "day" if there's only one day and drops leading zero in hours (as described in docstring of your current `str_timedelta` implementation, and this part is not true).

Of cause, premature optimizations are evil, so you 100% free to reject the PR, but it was very tempting to post this.