From 70b0088e020b1547ba951c0639586618fadcf5bb Mon Sep 17 00:00:00 2001 From: fawce Date: Tue, 22 May 2012 21:23:47 -0400 Subject: [PATCH 1/7] patched logging config. --- zipline/finance/performance.py | 2 -- zipline/logging.cfg | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index d72c229d..76231d2e 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -114,8 +114,6 @@ Performance Period import logging import datetime import pytz -import msgpack -import pandas import math import zmq diff --git a/zipline/logging.cfg b/zipline/logging.cfg index 911d2a2a..168420ac 100644 --- a/zipline/logging.cfg +++ b/zipline/logging.cfg @@ -20,7 +20,7 @@ qualname=ZiplineLogger class=handlers.RotatingFileHandler level=DEBUG formatter=ziplineformat -args=("/var/log/zipline/zipline.log",10*1024*1024,5) +args=("/var/log/zipline/zipline.log",'a',10*1024*1024,5) propagate=1 [handler_consoleHandler] From 89822748a74965d07f5ba58cae59ab63f92c5219 Mon Sep 17 00:00:00 2001 From: fawce Date: Wed, 23 May 2012 15:36:15 -0400 Subject: [PATCH 2/7] adding in vbench --- .gitignore | 3 + etc/requirements_dev.txt | 8 +- vb_suite/run_suite.py | 12 +++ vb_suite/suite.py | 111 ++++++++++++++++++++++++++++ vb_suite/zipline_bench_functions.py | 36 +++++++++ 5 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 vb_suite/run_suite.py create mode 100644 vb_suite/suite.py create mode 100644 vb_suite/zipline_bench_functions.py diff --git a/.gitignore b/.gitignore index 0bf8c4a7..38739d4f 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ docs/_build/* # credentials and other uncheckinables host_settings.py + +# database of vbench +benchmarks.db diff --git a/etc/requirements_dev.txt b/etc/requirements_dev.txt index fe90268c..c131f4a5 100644 --- a/etc/requirements_dev.txt +++ b/etc/requirements_dev.txt @@ -23,13 +23,6 @@ Sphinx==1.1.2 Paver==1.0.5 Paved==0.3 -# Testing -nose==1.1.2 -coverage==3.5.1 -mock==0.7.2 -nosexcover==1.0.7 -pylint==0.25.1 - # pycco deps Markdown==2.1.1 Pycco==0.3.0 @@ -39,3 +32,4 @@ wsgiref==0.1.2 # misc pycleaner==1.1.1 +-e git://github.com/pydata/vbench.git#egg=vbench diff --git a/vb_suite/run_suite.py b/vb_suite/run_suite.py new file mode 100644 index 00000000..c9b397e1 --- /dev/null +++ b/vb_suite/run_suite.py @@ -0,0 +1,12 @@ +from vbench.api import BenchmarkRunner +from suite import * + +def run_process(): + runner = BenchmarkRunner(benchmarks, REPO_PATH, REPO_URL, + BUILD, DB_PATH, TMP_DIR, PREPARE, + run_option='all', start_date=START_DATE, + module_dependencies=dependencies) + runner.run() + +if __name__ == '__main__': + run_process() diff --git a/vb_suite/suite.py b/vb_suite/suite.py new file mode 100644 index 00000000..ed6c016d --- /dev/null +++ b/vb_suite/suite.py @@ -0,0 +1,111 @@ +from vbench.api import Benchmark, GitRepo +from datetime import datetime + +import os + +modules = ['ziplines'] + +by_module = {} +benchmarks = [] + +for modname in modules: + ref = __import__(modname) + by_module[modname] = [v for v in ref.__dict__.values() + if isinstance(v, Benchmark)] + benchmarks.extend(by_module[modname]) + +for bm in benchmarks: + assert(bm.name is not None) + +import getpass +import sys + +USERNAME = getpass.getuser() + +if sys.platform == 'darwin': + HOME = '/Users/%s' % USERNAME +else: + HOME = '/home/%s' % USERNAME + +REPO_PATH = os.path.join(HOME, 'projects/qexec/zipline_repo') +REPO_URL = 'git@github.com:quantopian/zipline.git' +DB_PATH = os.path.join(REPO_PATH, 'vb_suite/benchmarks.db') +TMP_DIR = os.path.join(HOME, 'tmp/vb_zipline') + +PREPARE = """ +""" +BUILD = """ +""" +dependencies = ['zipline_bench_functions.py'] + +START_DATE = datetime(2011, 6, 1) + +repo = GitRepo(REPO_PATH) + +RST_BASE = 'source' + +# HACK! + +#timespan = [datetime(2011, 1, 1), datetime(2012, 1, 1)] + +def generate_rst_files(benchmarks): + import matplotlib as mpl + mpl.use('Agg') + import matplotlib.pyplot as plt + + vb_path = os.path.join(RST_BASE, 'vbench') + fig_base_path = os.path.join(vb_path, 'figures') + + if not os.path.exists(vb_path): + print 'creating %s' % vb_path + os.makedirs(vb_path) + + if not os.path.exists(fig_base_path): + print 'creating %s' % fig_base_path + os.makedirs(fig_base_path) + + for bmk in benchmarks: + print 'Generating rst file for %s' % bmk.name + rst_path = os.path.join(RST_BASE, 'vbench/%s.txt' % bmk.name) + + fig_full_path = os.path.join(fig_base_path, '%s.png' % bmk.name) + + # make the figure + plt.figure(figsize=(10, 6)) + ax = plt.gca() + bmk.plot(DB_PATH, ax=ax) + + start, end = ax.get_xlim() + + plt.xlim([start - 30, end + 30]) + plt.savefig(fig_full_path, bbox_inches='tight') + plt.close('all') + + fig_rel_path = 'vbench/figures/%s.png' % bmk.name + rst_text = bmk.to_rst(image_path=fig_rel_path) + with open(rst_path, 'w') as f: + f.write(rst_text) + + with open(os.path.join(RST_BASE, 'index.rst'), 'w') as f: + print >> f, """ +Performance Benchmarks +====================== + +These historical benchmark graphs were produced with `vbench +`__. + +.. toctree:: + :hidden: + :maxdepth: 3 +""" + for modname, mod_bmks in sorted(by_module.items()): + print >> f, ' vb_%s' % modname + modpath = os.path.join(RST_BASE, 'vb_%s.rst' % modname) + with open(modpath, 'w') as mh: + header = '%s\n%s\n\n' % (modname, '=' * len(modname)) + print >> mh, header + + for bmk in mod_bmks: + print >> mh, bmk.name + print >> mh, '-' * len(bmk.name) + print >> mh, '.. include:: vbench/%s.txt\n' % bmk.name diff --git a/vb_suite/zipline_bench_functions.py b/vb_suite/zipline_bench_functions.py new file mode 100644 index 00000000..565dee73 --- /dev/null +++ b/vb_suite/zipline_bench_functions.py @@ -0,0 +1,36 @@ +try: + from zipline.simulator import AddressAllocator + pass +except Exception, e: + from zipline.core.devsimulator import AddressAllocator + +from zipline.lines import SimulatedTrading + +allocator = AddressAllocator(1001) + + +def get_zipline(): + zipline_test_config = { + 'allocator':allocator, + 'sid':133 + } + + zipline = SimulatedTrading.create_test_zipline( + **zipline_test_config + ) + + return zipline + +def run_basic_zipline(): + zipline = get_zipline() + zipline.simulate(blocking=True) + +def load_ndict(): + from zipline import ndict + nd = ndict({}) + keyname = 'a %i' + for i in xrange(1000000): + nd[keyname % i] = i + + for i in xrange(1000000): + nd[keyname % i] From 92553abfa1660dbc116b2159603f86edc8b10e17 Mon Sep 17 00:00:00 2001 From: fawce Date: Wed, 23 May 2012 15:40:50 -0400 Subject: [PATCH 3/7] adding benchmark declarations. --- vb_suite/ziplines.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 vb_suite/ziplines.py diff --git a/vb_suite/ziplines.py b/vb_suite/ziplines.py new file mode 100644 index 00000000..3f74d669 --- /dev/null +++ b/vb_suite/ziplines.py @@ -0,0 +1,20 @@ +from vbench.api import Benchmark +from datetime import datetime + +setup = """ +from zipline_bench_functions import * +""" + +basic_zipline = Benchmark( + 'run_basic_zipline()', + setup=setup, + start_date=datetime(2012,4,15), + name='basic_zipline_test' +) + +load_ndict = Benchmark( + 'load_ndict', + setup=setup, + start_date=datetime(2012,4,15), + name='load_ndict' +) From f2aff6a501e75bf3986fca6669b3d713f66f9d89 Mon Sep 17 00:00:00 2001 From: fawce Date: Thu, 24 May 2012 16:42:15 -0400 Subject: [PATCH 4/7] fixed logger test. --- tests/test_logger.py | 33 ++------------------------------- zipline/utils/logger.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/tests/test_logger.py b/tests/test_logger.py index 050c7e29..9c7eb685 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -1,7 +1,7 @@ import logging import uuid -from zipline.utils.logger import configure_logging +from zipline.utils.logger import configure_logging, tail from unittest2 import TestCase @@ -17,35 +17,6 @@ class LoggerTestCase(TestCase): self.LOG.info(test_msg) logfile = open('/var/log/zipline/zipline.log','r') with logfile: - last_line = tail(logfile) + last_line = tail(logfile, window=1) logged_msg = last_line.split(" - ")[1] self.assertEqual(test_msg, logged_msg) - -def tail( f, window=20 ): - """ - from - http://stackoverflow.com/questions/136168/get-last-n-lines-of-a-file- \ - with-python-similar-to-tail - """ - BUFSIZ = 1024 - f.seek(0, 2) - bytes = f.tell() - size = window - block = -1 - data = [] - while size > 0 and bytes > 0: - if (bytes - BUFSIZ > 0): - # Seek back one whole BUFSIZ - f.seek(block*BUFSIZ, 2) - # read BUFFER - data.append(f.read(BUFSIZ)) - else: - # file too small, start from begining - f.seek(0,0) - # only read what was not read - data.append(f.read(bytes)) - linesFound = data[-1].count('\n') - size -= linesFound - bytes -= BUFSIZ - block -= 1 - return '\n'.join(''.join(data).splitlines()[-window:]) diff --git a/zipline/utils/logger.py b/zipline/utils/logger.py index bc48f870..03ef58a8 100644 --- a/zipline/utils/logger.py +++ b/zipline/utils/logger.py @@ -17,3 +17,34 @@ def logger_path(): import zipline log_path = dirname(abspath(zipline.__file__)) return join(log_path, 'logging.cfg') + + +# utility for tailing a log file. +def tail( f, window=20 ): + """ + from + http://stackoverflow.com/questions/136168/get-last-n-lines-of-a-file- \ + with-python-similar-to-tail + """ + BUFSIZ = 1024 + f.seek(0, 2) + bytes = f.tell() + size = window + block = -1 + data = [] + while size > 0 and bytes > 0: + if (bytes - BUFSIZ > 0): + # Seek back one whole BUFSIZ + f.seek(block*BUFSIZ, 2) + # read BUFFER + data.append(f.read(BUFSIZ)) + else: + # file too small, start from begining + f.seek(0,0) + # only read what was not read + data.append(f.read(bytes)) + linesFound = data[-1].count('\n') + size -= linesFound + bytes -= BUFSIZ + block -= 1 + return '\n'.join(''.join(data).splitlines()[-window:]) From 31b545946ed16ce16f49536641351c86de91f9fa Mon Sep 17 00:00:00 2001 From: fawce Date: Fri, 25 May 2012 11:11:18 -0400 Subject: [PATCH 5/7] performance tweak on ndict's frozenset. --- zipline/utils/__init__.py | 1 - zipline/utils/protocol_utils.py | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/zipline/utils/__init__.py b/zipline/utils/__init__.py index 8a1b7b26..1bdceb03 100644 --- a/zipline/utils/__init__.py +++ b/zipline/utils/__init__.py @@ -1,5 +1,4 @@ from protocol_utils import ndict - __all__ = [ ndict, ] diff --git a/zipline/utils/protocol_utils.py b/zipline/utils/protocol_utils.py index 376fc8c7..180f127a 100644 --- a/zipline/utils/protocol_utils.py +++ b/zipline/utils/protocol_utils.py @@ -40,9 +40,11 @@ class ndict(MutableMapping): this time. """ + cls = None + def __init__(self, dct=None): self.__internal = dict() - self.cls = frozenset(dir(self)) + self.cls = self.cls or frozenset(dir(self)) if dct: self.__internal.update(dct) @@ -51,7 +53,7 @@ class ndict(MutableMapping): # ----------------- def __setattr__(self, key, value): - if '_ndict' in key or key == 'cls': + if '_ndict' in key or key == 'cls' or key == '__internal': self.__dict__[key] = value else: self.__internal[key] = value @@ -84,7 +86,7 @@ class ndict(MutableMapping): def __len__(self): return len(self.__internal) - # Compatability with namedicts + # Compatability with ndicts # ---------------------------- # for compat, not the Python way to do things though... @@ -136,7 +138,7 @@ class ndict(MutableMapping): self.__internal.update(other_nd.__internal) def __repr__(self): - return "namedict: " + str(self.__internal) + return "ndict: " + str(self.__internal) # Faster dictionary comparison? #def __eq__(self, other): From b533961247b5bfda2860eb114dd1bf42b8ea2de4 Mon Sep 17 00:00:00 2001 From: fawce Date: Fri, 25 May 2012 11:15:56 -0400 Subject: [PATCH 6/7] little more perf tweaking. --- zipline/utils/protocol_utils.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/zipline/utils/protocol_utils.py b/zipline/utils/protocol_utils.py index 180f127a..c0b7ad16 100644 --- a/zipline/utils/protocol_utils.py +++ b/zipline/utils/protocol_utils.py @@ -41,10 +41,13 @@ class ndict(MutableMapping): """ cls = None + __slots__ = ['cls', '__internal'] def __init__(self, dct=None): self.__internal = dict() - self.cls = self.cls or frozenset(dir(self)) + + if not ndict.cls: + ndict.cls = frozenset(dir(self)) if dct: self.__internal.update(dct) @@ -53,8 +56,8 @@ class ndict(MutableMapping): # ----------------- def __setattr__(self, key, value): - if '_ndict' in key or key == 'cls' or key == '__internal': - self.__dict__[key] = value + if key == 'cls' or key == '__internal' or '_ndict' in key: + super(ndict, self).__setattr__(key, value) else: self.__internal[key] = value return value @@ -70,7 +73,7 @@ class ndict(MutableMapping): def __getattr__(self, key): if key in self.cls: - return self.__dict__[key] + super(ndict, self).__getattr__(key) else: return self.__internal[key] @@ -86,7 +89,7 @@ class ndict(MutableMapping): def __len__(self): return len(self.__internal) - # Compatability with ndicts + # Compatability with namedicts # ---------------------------- # for compat, not the Python way to do things though... @@ -138,7 +141,7 @@ class ndict(MutableMapping): self.__internal.update(other_nd.__internal) def __repr__(self): - return "ndict: " + str(self.__internal) + return "namedict: " + str(self.__internal) # Faster dictionary comparison? #def __eq__(self, other): From 35c034eb3195f36734c3a761c0c522bf93ba5002 Mon Sep 17 00:00:00 2001 From: fawce Date: Fri, 25 May 2012 12:42:29 -0400 Subject: [PATCH 7/7] shortened up the tests to make them more reasonable total runtime. --- vb_suite/zipline_bench_functions.py | 7 +++++++ vb_suite/ziplines.py | 11 +++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/vb_suite/zipline_bench_functions.py b/vb_suite/zipline_bench_functions.py index 565dee73..c970f055 100644 --- a/vb_suite/zipline_bench_functions.py +++ b/vb_suite/zipline_bench_functions.py @@ -34,3 +34,10 @@ def load_ndict(): for i in xrange(1000000): nd[keyname % i] + +def mass_create_ndict(): + from zipline import ndict + data = dict(('a %d' % a,a) for a in xrange(1000)) + + for i in xrange(10000): + ndict(data) diff --git a/vb_suite/ziplines.py b/vb_suite/ziplines.py index 3f74d669..fd3fba0a 100644 --- a/vb_suite/ziplines.py +++ b/vb_suite/ziplines.py @@ -8,13 +8,20 @@ from zipline_bench_functions import * basic_zipline = Benchmark( 'run_basic_zipline()', setup=setup, - start_date=datetime(2012,4,15), + start_date=datetime(2012,5,15), name='basic_zipline_test' ) load_ndict = Benchmark( - 'load_ndict', + 'load_ndict()', setup=setup, start_date=datetime(2012,4,15), name='load_ndict' ) + +mass_create_ndict = Benchmark( + 'mass_create_ndict()', + setup=setup, + start_date=datetime(2012,5,1), + name='create_ndict' +)