給vnTrader 1.92版本加入lru_cache快取讀取提速優化回測
VnTrader 2.0版本有不少提速措施,其中lru_cache是提高回測速度一個利器,讓我用1.92為主的我很是羨慕。看說這個是python 3.5.2提供的功能,也就沒多想。
最近才發現其實有第三方在也支援python 2.7的版本,比如 functools32。還有一個用 C 語言實現的,更快的,同時相容 Python2 和 Python3 的第三方模組 fastcache 能夠實現同樣的功能,這裡就用fastcache。
安裝
很簡單,pip直接安裝就可以。
pip install fastcache --upgrade
測試是否正確安裝
import fastcache fastcache.test()
簡單使用
- 不用cache時候,執行時間 0.7994769 秒
from fastcache import clru_cache def fib(n): if n < 2: return n return fib(n - 2) + fib(n - 1) import time dt0 = time.clock() for i in range(30): fib(i) spreadtime = (time.clock() - dt0) print ("執行時間 %s 秒" %spreadtime)
- 使用後,執行時間 0.000185200000004 秒
@clru_cache(maxsize=999) def fib_cache(n): if n < 2: return n return fib_cache(n - 2) + fib_cache(n - 1) import time dt1 = time.clock() for i in range(30): fib_cache(i) spreadtime = (time.clock() - dt1) print ("執行時間 %s 秒" %spreadtime)
使用clru_cache, 更新trader/app/ctaStrategy/ctaBacktesting.py, 讓回測歷史資料快取到記憶體,不用反覆讀取
- 通常只在靜態方法使用lru_cache,這樣才具有意義, 雖然在類方法中也可以使用,但是這樣一個是有不同例項一般無法複用,而且會使得過期例項無法垃圾回收。這裡新建一個靜態方法load_data,負責讀取資料庫資料。
@clru_cache(maxsize=9999) def load_data(dbName, symbol, dataStartDate, strategyStartDate, dataEndDate, dataClass): dbClient = pymongo.MongoClient(globalSetting['mongoHost'], globalSetting['mongoPort']) collection = dbClient[dbName][symbol] # 載入初始化需要用的資料 flt = {'datetime': {'$gte': dataStartDate, '$lt': strategyStartDate}} initCursor = collection.find(flt).sort('datetime') initData = [] # 清空initData列表 for d in initCursor: data = dataClass() data.__dict__ = d initData.append(data) # 載入回測資料 if not dataEndDate: flt = {'datetime': {'$gte': strategyStartDate}} # 資料過濾條件 else: flt = {'datetime': {'$gte': strategyStartDate, '$lte': dataEndDate}} BackData = [] dbCursor = collection.find(flt).sort('datetime') for dc in dbCursor: data = dataClass() data.__dict__ = dc BackData.append(data) count = len(initData) + len(BackData) return initData, BackData, count
- 修改已有方法BacktestingEngine.loadHistoryData; 改為使用剛剛建立靜態方法
def loadHistoryData(self): """載入歷史資料""" self.output(u'開始載入資料') # 首先根據回測模式,確認要使用的資料類 # load_data(dbName, symbol, dataStartDate, strategyStartDate, dataEndDate, dataClass) if self.mode == self.BAR_MODE: dataClass = VtBarData func = self.newBar self.initData,self.BackTestData, count = load_data(self.dbName,self.symbol, self.dataStartDate, self.strategyStartDate, self.dataEndDate, dataClass) else: dataClass = VtTickData func = self.newTick self.initData, self.BackTestData, count = load_data(self.dbName, self.symbol, self.dataStartDate, self.strategyStartDate, self.dataEndDate, dataClass) # 載入初始化需要用的資料 if self.hdsClient: initCursor = self.hdsClient.loadHistoryData(self.dbName, self.symbol, self.dataStartDate, self.strategyStartDate) # 將資料從查詢指標中讀取出,並生成列表 self.initData = [] # 清空initData列表 for d in initCursor: data = dataClass() data.__dict__ = d self.initData.append(data) # 載入回測資料 self.dbCursor = self.hdsClient.loadHistoryData(self.dbName, self.symbol, self.strategyStartDate, self.dataEndDate) for dc in self.dbCursor: data = dataClass() data.__dict__ = dc self.BackTestData.append(data) self.output(u'載入完成,資料量:%s' % count)
-
修改 BacktestingEngine.runBacktesting; 改為使用換成的BackTestData 佇列,而不是資料庫指標。
def runBacktesting(self): """執行回測""" # 載入歷史資料 self.loadHistoryData() # 首先根據回測模式,確認要使用的資料類 if self.mode == self.BAR_MODE: dataClass = VtBarData func = self.newBar else: dataClass = VtTickData func = self.newTick self.output(u'開始回測') self.strategy.onInit() self.strategy.inited = True self.output(u'策略初始化完成') self.strategy.trading = True self.strategy.onStart() self.output(u'策略啟動完成') self.output(u'開始回放資料') for d in self.BackTestData: func(d) self.output(u'資料回放結束')
沒有使用之前,優化約為100組引數約為執行時間 323.0888239 秒,使用cache優化後執行時間 190.762839 秒
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2660092/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 頁面快取優化快取優化
- redis快取優化案例Redis快取優化
- nginx快取與優化Nginx快取優化
- MySQL 效能優化之快取引數優化MySql優化快取
- 優化MySQL,還是使用快取?優化MySql快取
- 優化MySQL 還是使用快取?優化MySql快取
- 快取最佳化(快取穿透)快取穿透
- 優化-瀏覽器快取和壓縮優化優化瀏覽器快取
- Laravel 優化 Auth 使用快取驅動Laravel優化快取
- 前端效能優化之快取技術前端優化快取
- 前端效能優化之HTTP快取策略前端優化HTTP快取
- Laravel Passport 使用快取優化記錄LaravelPassport快取優化
- LAMP和LNMP加速與快取優化LAMPLNMP快取優化
- 快取檢測快取
- 圖片優化瘦身 給網站提速優化網站
- 關於瀏覽器快取問題(圖片更換後,頁面仍優先讀取快取)瀏覽器快取
- python自帶快取lru_cache用法及擴充套件(詳細)Python快取套件
- HTTP前端效能優化(壓縮與快取)HTTP前端優化快取
- Web 效能優化:理解及使用 JavaScript 快取Web優化JavaScript快取
- Web靜態資源快取及優化Web快取優化
- 前端效能優化 之 瀏覽器快取前端優化瀏覽器快取
- MySQL 資料庫效能優化之快取引數優化MySql資料庫優化快取
- 一文讀懂快取穿透、快取擊穿、快取雪崩及其解決方案快取穿透
- 給 App 提速:Android 效能優化總結APPAndroid優化
- 精讀《函式快取》函式快取
- Vue專案全域性配置頁面快取,實現按需讀取快取Vue快取
- 快取穿透、快取擊穿、快取雪崩、快取預熱快取穿透
- Masa Framework原始碼解讀-02快取模組(分散式快取進階之多級快取)Framework原始碼快取分散式
- MySQL資料庫效能優化之快取引數優化(轉)MySql資料庫優化快取
- MySQL 資料庫的提速器-寫快取(Change Buffer)MySql資料庫快取
- 【譯】Web 效能優化:理解及使用 JavaScript 快取Web優化JavaScript快取
- [譯]谷歌Web效能優化系列:HTTP 快取(中英)谷歌Web優化HTTP快取
- LAMP與LNMP加速與快取優化(一)2LAMPLNMP快取優化
- 快取穿透、快取擊穿、快取雪崩快取穿透
- 快取穿透、快取雪崩、快取擊穿快取穿透
- Redis快取擊穿、快取穿透、快取雪崩Redis快取穿透
- HTTP快取——協商快取(快取驗證)HTTP快取
- [Redis]快取穿透/快取擊穿/快取雪崩Redis快取穿透