Commit 85faaafb by John Eskew

Update README. Make thread-safe. Use file-relative path to schema.

parent e4d9750b
Python module which puts timing around Python code blocks.
Python module which times Python code blocks.
Features
--------
* Nesting of timers - higher level timers continue to tick during lower-level timers starting/stopping.
* Timing storage in a SQLite DB.
Usage
-----
```
from code_block_timer import CodeBlockTimer
for i in xrange(0, 2):
with CodeBlockTimer("all blocks"):
performSetUp()
with CodeBlockTimer("block1"):
perform_lengthy_task()
with CodeBlockTimer("block2"):
perform_another_lengthy_task()
```
In the SQLite DB, you'll now see six rows, similar to these:
```
1|1|all blocks:block1|201.16|2014-10-12 12:26:01
2|1|all blocks:block2|516.492|2014-10-12 12:26:01
3|1|all blocks|916.54|2014-10-12 12:26:01
4|2|all blocks:block1|199.16|2014-10-12 12:26:04
5|2|all blocks:block2|505.142|2014-10-12 12:26:04
6|2|all blocks|903.212|2014-10-12 12:26:04
```
import threading
from timeit import default_timer
from .storage import TimingDataStorage
class Globals(object):
pass
class Globals(threading.local):
# Current module-level nest stack.
# As CodeBlockTimer objects are __enter__ed, their descriptions are pushed
# onto this stack. The stack length indicates the current nesting level.
nest_stack = []
_m = Globals()
# Current run_id.
# Set from data storage when stack size increases from 0.
# While nest stack is populated, remains at a constant value.
# Identifies all the times from the same run.
run_id = None
# Current module-level nest stack.
# As CodeBlockTimer objects are __enter__ed, their descriptions are pushed
# onto this stack. The stack length indicates the current nesting level.
_m.nest_stack = []
# Current run_id.
# Set from data storage when stack size increases from 0.
# While nest stack is populated, remains at a constant value.
# Identifies all the times from the same run.
_m.run_id = None
_m = Globals()
class CodeBlockTimer(object):
......@@ -28,7 +28,6 @@ class CodeBlockTimer(object):
self.data_store = TimingDataStorage(**kwargs)
def __enter__(self):
global _m
if len(_m.nest_stack) == 0:
_m.run_id = self.data_store.run_id()
_m.nest_stack.append(self.block_desc)
......@@ -36,8 +35,6 @@ class CodeBlockTimer(object):
return self
def __exit__(self, *args):
global _m
# Compute elapsed times.
end = self.timer()
self.elapsed_secs = end - self.start
......
import sqlite3
import os
import sqlite3
from path import path
# Assumes that the DB exists and the schema in schema.sql exists in it.
MODULE_DIR = path(__file__).dirname()
class TimingDataStorage(object):
SCHEMA_NAME = 'schema.sql'
SCHEMA_PATH = MODULE_DIR / self.SCHEMA_NAME
DEFAULT_DB_NAME = 'block_times.db'
def __init__(self, **kwargs):
......@@ -23,8 +27,7 @@ class TimingDataStorage(object):
# Create the sqlite DB file.
with open(db_name, "w") as f:
conn = sqlite3.connect(db_name)
schema_filepath = os.path.join(os.path.dirname(__file__), self.SCHEMA_NAME)
with open(schema_filepath, "r") as schema_file:
with open(self.SCHEMA_PATH, "r") as schema_file:
schema = schema_file.read()
cur = conn.cursor()
conn.executescript(schema)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment