mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-06 05:14:38 +08:00
PERF: Optimized rewrite of HistoryContainer.update.
Uses a numpy array instead of a dict of dicts when initializing history
container.
In testing this reduced the total time spent in HistoryContainer.update
by 66%.
BEFORE COMMIT:
Thu Oct 16 22:30:46 2014 results/cprofile/unoptimized
185223320 function calls (182210491 primitive calls) in 401.351
seconds
Ordered by: cumulative time
List reduced from 2398 to 27 due to restriction <'update'>
ncalls tottime percall cumtime percall filename:lineno(function)
8580 0.461 0.000 160.571 0.019
qexec/zipline/history/history_container.py:388(update)
AFTER COMMIT:
Thu Oct 16 22:12:28 2014 results/cprofile/optimized
143177181 function calls (140164352 primitive calls) in 272.403
seconds
Ordered by: cumulative time
List reduced from 2395 to 27 due to restriction <'update'>
ncalls tottime percall cumtime percall filename:lineno(function)
8580 0.086 0.000 47.294 0.006 qexec/zipline/history/history_container.py:388(update)
This commit is contained in:
@@ -361,22 +361,35 @@ class HistoryContainer(object):
|
||||
# earliest_minute and latest_minute, which is what we want.
|
||||
return buffer_panel.ix[:, earliest_minute:latest_minute, :]
|
||||
|
||||
def frame_from_bardata(self, data, algo_dt):
|
||||
"""
|
||||
Create a DataFrame from the given BarData and algo dt.
|
||||
"""
|
||||
data = data._data
|
||||
frame_data = np.ones((len(self.sids), len(self.fields))) * np.nan
|
||||
|
||||
for i, sid in enumerate(self.sids):
|
||||
sid_data = data.get(sid)
|
||||
if not sid_data:
|
||||
continue
|
||||
if algo_dt != sid_data['dt']:
|
||||
continue
|
||||
for j, field in enumerate(self.fields):
|
||||
frame_data[i, j] = sid_data.get(field, np.nan)
|
||||
|
||||
return pd.DataFrame(
|
||||
frame_data,
|
||||
index=self.sids.copy(),
|
||||
columns=self.fields.copy(),
|
||||
).T
|
||||
|
||||
def update(self, data, algo_dt):
|
||||
"""
|
||||
Takes the bar at @algo_dt's @data, checks to see if we need to roll any
|
||||
new digests, then adds new data to the buffer panel.
|
||||
"""
|
||||
frame = pd.DataFrame(
|
||||
{
|
||||
sid: {field: bar[field] for field in self.fields}
|
||||
for sid, bar in data.iteritems()
|
||||
# data contains the latest values seen for each security in our
|
||||
# universe. If a stock didn't trade this dt, then it will
|
||||
# still have an entry in data, but its dt will be behind the
|
||||
# algo_dt.
|
||||
if (bar and bar['dt'] == algo_dt and sid in self.sids)
|
||||
}
|
||||
)
|
||||
|
||||
frame = self.frame_from_bardata(data, algo_dt)
|
||||
|
||||
self.update_last_known_values()
|
||||
self.update_digest_panels(algo_dt, self.buffer_panel)
|
||||
|
||||
@@ -210,6 +210,9 @@ class SIDData(object):
|
||||
"""
|
||||
return self.dt
|
||||
|
||||
def get(self, name, default):
|
||||
return self.__dict__.get(name, default)
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.__dict__[name]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user