69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
from __future__ import print_function
|
|
import hotshot
|
|
import os
|
|
import time
|
|
|
|
from django.conf import settings
|
|
|
|
from django.db import connection
|
|
|
|
try:
|
|
PROFILE_LOG_BASE = settings.PROFILE_LOG_BASE
|
|
except:
|
|
PROFILE_LOG_BASE = "/tmp"
|
|
|
|
|
|
def profile(log_file):
|
|
"""Profile some callable.
|
|
|
|
This decorator uses the hotshot profiler to profile some callable (like
|
|
a view function or method) and dumps the profile data somewhere sensible
|
|
for later processing and examination.
|
|
|
|
It takes one argument, the profile log name. If it's a relative path, it
|
|
places it under the PROFILE_LOG_BASE. It also inserts a time stamp into the
|
|
file name, such that 'my_view.prof' become 'my_view-20100211T170321.prof',
|
|
where the time stamp is in UTC. This makes it easy to run and compare
|
|
multiple trials.
|
|
"""
|
|
|
|
if not os.path.isabs(log_file):
|
|
log_file = os.path.join(PROFILE_LOG_BASE, log_file)
|
|
|
|
def _outer(f):
|
|
def _inner(*args, **kwargs):
|
|
# Add a timestamp to the profile output when the callable
|
|
# is actually called.
|
|
(base, ext) = os.path.splitext(log_file)
|
|
base = base + "-" + time.strftime("%Y%m%dT%H%M%S", time.gmtime())
|
|
final_log_file = base + ext
|
|
|
|
prof = hotshot.Profile(final_log_file)
|
|
try:
|
|
ret = prof.runcall(f, *args, **kwargs)
|
|
finally:
|
|
prof.close()
|
|
return ret
|
|
|
|
return _inner
|
|
return _outer
|
|
|
|
def timethis(fn):
|
|
def wrapper(*args, **kwargs):
|
|
start = time.time()
|
|
result = fn(*args, **kwargs)
|
|
print(fn.__name__, 'took', time.time() - start)
|
|
return result
|
|
|
|
return wrapper
|
|
|
|
from pprint import pprint
|
|
|
|
def sqlprint(fn):
|
|
def wrapper(*args, **kwargs):
|
|
connection.queries = list()
|
|
result = fn(*args, **kwargs)
|
|
print(fn.__name__, 'issued')
|
|
pprint(connection.queries)
|
|
return result
|
|
return wrapper |