Python 分析、导入(特别是 __init__)似乎花费的时间最多
Python profiling, imports (and specially __init__) is what seems to take the most time
我有一个脚本似乎 运行 很慢,我使用 cProfile(和可视化工具 KCacheGrind)进行了概要分析
导入顺序似乎占了 运行 时间的将近 90%,尤其是 _ _ init _ _.py
文件的 运行ning...
这里是 KCacheGrind 输出的屏幕截图(抱歉附上图片...)
我不太熟悉 python 中的导入顺序是如何工作的,所以也许我有些困惑...我还在我的每个定制包中放置了 _ _ init _ _.py
文件,而不是确定那是否是我应该做的。
无论如何,如果有人有任何提示,不胜感激!
编辑:功能自行排序时的附加图片:
编辑 2:
此处附上代码,以便回答者更加清楚:
from strategy.strategies.gradient_stop_and_target import make_one_trade
from datetime import timedelta, datetime
import pandas as pd
from data.db import get_df, mongo_read_only, save_one, mongo_read_write, save_many
from data.get import get_symbols
from strategy.trades import make_trade, make_mae, get_prices, get_signals, \
get_prices_subset
#from profilehooks import profile
mongo = mongo_read_only()
dollar_stop = 200
dollar_target = 400
period_change = 3
signal = get_df(mongo.signals.signals, strategy = {'$regex' : '^indicators_group'}).iloc[0]
symbol = get_symbols(mongo, description = signal['symbol'])[0]
prices = get_prices(
signal['datetime'],
signal['datetime'].replace(hour = 23, minute = 59),
symbol,
mongo)
make_one_trade(
signal,
prices,
symbol,
dollar_stop,
dollar_target,
period_change)
函数get_prices只是从mongo数据库中获取数据,make_one_trade用pandas做简单的计算。这在我项目的其他任何地方都不会造成问题。
编辑 3:
这里是 Kcache grind screen when i select 'detect cycle' option in View tab:
这是否真的意味着我自己创建的包中确实存在循环导入,需要花费那么多时间来解决?
没有。您将 累积时间 与在 __init__.py
文件本身的顶级代码中花费的时间混为一谈。顶层代码调用其他方法,一起需要很多时间。
改为查看 self 列以查找所有时间都花在了哪里。另见What is the difference between tottime and cumtime in a python script profiled with cProfile?,incl.栏是累计时间,self是总时间。
我只是过滤掉所有 <frozen importlib.*>
条目; Python 项目已经确保优化了这些路径。
但是,您的第二个屏幕截图确实表明,在您的分析 运行 中,您的 Python 代码忙于加载要导入的模块的字节码(marshal
module 提供了Python 字节码序列化实现)。 Python 程序除了导入模块什么也没做,没有做其他工作,或者它正在使用某种形式的动态导入加载大量模块,或者忽略正常的模块缓存并重新加载相同的模块(s) 重复。
您可以使用 Python 3.7 的新功能 -X importtime
command-line switch, or you could use a dedicated import-profiler 分析导入时间,找出为什么导入需要这么长时间。
我有一个脚本似乎 运行 很慢,我使用 cProfile(和可视化工具 KCacheGrind)进行了概要分析
导入顺序似乎占了 运行 时间的将近 90%,尤其是 _ _ init _ _.py
文件的 运行ning...
这里是 KCacheGrind 输出的屏幕截图(抱歉附上图片...)
我不太熟悉 python 中的导入顺序是如何工作的,所以也许我有些困惑...我还在我的每个定制包中放置了 _ _ init _ _.py
文件,而不是确定那是否是我应该做的。
无论如何,如果有人有任何提示,不胜感激!
编辑:功能自行排序时的附加图片:
编辑 2:
此处附上代码,以便回答者更加清楚:
from strategy.strategies.gradient_stop_and_target import make_one_trade
from datetime import timedelta, datetime
import pandas as pd
from data.db import get_df, mongo_read_only, save_one, mongo_read_write, save_many
from data.get import get_symbols
from strategy.trades import make_trade, make_mae, get_prices, get_signals, \
get_prices_subset
#from profilehooks import profile
mongo = mongo_read_only()
dollar_stop = 200
dollar_target = 400
period_change = 3
signal = get_df(mongo.signals.signals, strategy = {'$regex' : '^indicators_group'}).iloc[0]
symbol = get_symbols(mongo, description = signal['symbol'])[0]
prices = get_prices(
signal['datetime'],
signal['datetime'].replace(hour = 23, minute = 59),
symbol,
mongo)
make_one_trade(
signal,
prices,
symbol,
dollar_stop,
dollar_target,
period_change)
函数get_prices只是从mongo数据库中获取数据,make_one_trade用pandas做简单的计算。这在我项目的其他任何地方都不会造成问题。
编辑 3:
这里是 Kcache grind screen when i select 'detect cycle' option in View tab:
这是否真的意味着我自己创建的包中确实存在循环导入,需要花费那么多时间来解决?
没有。您将 累积时间 与在 __init__.py
文件本身的顶级代码中花费的时间混为一谈。顶层代码调用其他方法,一起需要很多时间。
改为查看 self 列以查找所有时间都花在了哪里。另见What is the difference between tottime and cumtime in a python script profiled with cProfile?,incl.栏是累计时间,self是总时间。
我只是过滤掉所有 <frozen importlib.*>
条目; Python 项目已经确保优化了这些路径。
但是,您的第二个屏幕截图确实表明,在您的分析 运行 中,您的 Python 代码忙于加载要导入的模块的字节码(marshal
module 提供了Python 字节码序列化实现)。 Python 程序除了导入模块什么也没做,没有做其他工作,或者它正在使用某种形式的动态导入加载大量模块,或者忽略正常的模块缓存并重新加载相同的模块(s) 重复。
您可以使用 Python 3.7 的新功能 -X importtime
command-line switch, or you could use a dedicated import-profiler 分析导入时间,找出为什么导入需要这么长时间。