因为看到有人反应,重覆登出登入,会造成记忆体使用量增加,这实在是让人太好奇了,所以就想来实测一下。但因为反应问题的人也没有提供程序内容,所以只是自己猜可能的程序内容
测试程序范例:
import os, psutil, gc, time
import shioaji as sj
from dotenv import load_dotenv
load_dotenv('D:\\python\\shioaji\\.env') #读取.env中的环境变数
process = psutil.Process(os.getpid())
print(f'mem usage as start: {process.memory_info()[0]/float(2 ** 20)}kb')
for i in range(5):
api = sj.Shioaji(simulation=True)
print(f'({i})mem usage at api initial: {process.memory_info()[0]/float(2 ** 20)}kb')
api.login(
person_id='PAPIUSER01',
passwd='2222'
)
print(f'({i})mem usage at api.login: {process.memory_info()[0]/float(2 ** 20)}kb')
api.logout()
time.sleep(10) #登出後,等待10秒再进行登入,防止出错
del api
gc.collect()
print(f'mem usage after del api: {process.memory_info()[0]/float(2 ** 20)}kb')
上面用for in的方式重覆进行5次初始化、登入及登出动作,来测试是否有产生RAM使用量增加的情况,在测试时发现若登入的环境是测试环境,虽然RAM使用量有增加,但其实不明显。而上面这个范例,是用测试环境及帐号进行测试,若是正式环境,只需传入自己的帐号密码,并且在初始化时,不设定simulation=True即可。
测试结果如下(单位:KB):
程序点 | windows&正式环境 | windows&测试环境 | ubuntu&正式环境 | ubuntu&测试环境 |
---|---|---|---|---|
start | 33.98828125 | 33.84375 | 34.59765625 | 34.5 |
0-initial | 38 | 37.89453125 | 37.98828125 | 37.84765625 |
0-login | 126.1132813 | 39.3671875 | 72.94140625 | 39.03515625 |
1-initial | 227.5351563 | 40.23828125 | 203.6210938 | 39.87109375 |
1-login | 219.4492188 | 40.125 | ||
2-initial | 409.7734375 | 41.18359375 | 225.5703125 | 40.3828125 |
2-login | 471.53125 | 41.90234375 | 239.6914063 | 40.63671875 |
3-initial | 591.7265625 | 42 | 264.2929688 | 40.63671875 |
3-login | 642.1875 | 42.72265625 | 286.9375 | 40.890625 |
4-initial | 775.7148438 | 42.84765625 | 328.703125 | 41.1484375 |
4-login | 844.2929688 | 43.55859375 | 354.390625 | 41.40234375 |
del & gc | 956.984375 | 42.75 | 494.125 | 41.52734375 |
由测试结果可以看到,的确这样的写法是会增加许多RAM的使用量,不过在Linux环境中,增加的量不像在Windows下那样夸张。而测试环境的部份,竟然差异不大,这可能要请开发团队看才能知道为何有这差异。
其实RAM使用量增加主要是因为重覆执行sj.Shioaji()进行初始化动作所造成,虽然执行login()後,RAM使用量也会增加,但并没有像执行sj.Shioaji()时增加那麽多。解决方式可分为下列2种:
1.sj.Shioaji()移至回圈或是function外层,避免重覆执行
2.在login时,传入fetch_contract=False,即不执行fetch_all_contract动作,预先抓所有的contract
我个人比较便好1,因为只需要将原本的程序做一点小调整即可。
第2种方式虽然也可以,但是Contract物件经常会被使用到,若指定fetch_contract=False,则无法透过api取得Contract内容,也就要考虑用object serialization先将Contract物件储存起来,要用的时候再做读取的动作。
在做投资之前,首先最重要的事,当然就是得先去开一个证券户啦~~~ 什麽是证券户? 简而言之,一般我们...
生活上我们可能有遇过一些二分搜寻的例子。 例如以前如果有当过助教的经验,有时候我们在收学生作业时会作...
参赛初衷 今年的参赛题目是「不只懂语法:Vue.js 观念篇」。去年的这时候刚刚学 JavaScri...
今天我们会用部落格跟使用者的关系来讲解关联,首先先做设定,部落格跟使用者的关系为 使用者对应多个部落...
<img src="https://miro.medium.com/max/700/0*4Pr...