使用从循环内的代码片段中提取的函数避免代码冗余/计算开销

如何解决使用从循环内的代码片段中提取的函数避免代码冗余/计算开销

我有一个循环,它循环金融时间序列的天数和离散时间段,其中包含一些用于我的策略的代码。我将这个内部代码提取一个独立的函数中,以便能够在特定情况下使用它进行测试,后来才发现这个操作大大增加了这个循环的总计算时间。这是有道理的,长函数签名、调用、(堆栈内存?)所有这些都必须引入一些开销。

# Fast,but cannot use my strategy for specific instances:
for d in data:
    # my strategy code

# Flexible but really slow
def my_strategy(**params):
    # my strategy code
f = partial(my_strategy,**params)
for d in data:
    f(d)

现在,我的问题是:有没有办法在没有显式冗余的情况下同时保留两个设置、独立函数以及带有循环和实际代码的设置?我需要两者兼而有之。

我一直在尝试使用 inspect.getsource(my_function) 并包装外部函数的副本,然后使用 eval,但 5 分钟后我觉得自己像个白痴,感觉一点也不对。

>

解决此问题的最佳做法是什么?如果我复制代码,我必须确保如果我修改一个版本,另一个版本总是同步的。我不喜欢这个。我想有效地镜像它。

正如您可能已经想到的那样,一种选择可能是:将代码保留在循环内的原处,并在需要时用数组包装您的特定案例并将其提供给循环。好吧,我不能这样做,主要是因为我需要对内部代码执行进行定时控制(我将回溯测试的策略移植到实时)。在这里,我只是在寻找一些快速的技巧来优雅地镜像代码(如果有的话)。

--- 编辑---

好的,为了进一步测试这个,我实现了我提到的那个可怕的黑客,我让它与 exec 一起工作。多亏了这一点,我现在可以保证使用的代码完全相同。观察到的时差是相同的。包含代码的循环大约需要函数调用循环所用时间的一半。

# horrible hack,please forgive me
def extract_strategy_function():
    # Start
    source_code = inspect.getsource(fastest_compute_Trades)
    # Cutting the code snippet
    source_code = source_code.split('[safe_start - 1:]:',1)[1].rsplit("if s['pos_open']:",1)[0]
    # Needs re-indentation so the parser doesn't complain
    source_code = reindent(source_code,-2)
    function_name = 'single_apply_strategy'  # internal,no-one will see this anyway
    function_string = f"""
    def {function_name}(
            # INDICATORS (non mutable)
            i_time,close_price,r2,ma1,ma2,rsi,upper,lower,# STATE VARIABLES,TX HISTORY (mutable,2 dictionaries and 1 list of dicts)
            s,gs,transactions,# CONSTANT ParaMETERS (non mutable)
            min_r2,macd_threshold,rsi_bound,waiting_slots,stop_loss,take_profit,trail_profit,double_down,dd_qty,commission_fee,# Day ID,useful when back-testing/grid-searching,left at the end so it can default to 0
            i_day=0
    ):
    {source_code}
    """.strip()
    # Evaluate it
    exec(function_string)  # Now in locals
    return locals()[function_name]
    
def slow(...):
    
    ...
    
    apply_strategy = partial(extract_strategy_function(),**params,commission_fee=commission_fee,rsi_bound=rsi_bound)
   
    for i_day,day in enumerate(data):
        for i_time,in list(enumerate(day))[safe_start - 1:]:
            apply_strategy(i_time,day_state,global_state,i_day=i_day)

        if day_state['pos_open']:
            ...
    
    ...
    
def fast(...,#some extra parameters are Now unpacked here,#since all code is here they are Now needed here
):
    ...
    
    for i_day,in list(enumerate(day))[safe_start - 1:]:
            # actual code contained in single_apply_strategy written here,the whole strategy (one timestep)

        if day_state['pos_open']:
            ...
            
    ...

有什么建议吗?

附言不用说,两种设置的输出完全一样

解决方法

由函数调用引起的任何开销很可能可以忽略不计。使用您的函数,并在需要时通过“手动内联”您的函数来衡量可能的改进。

如果您需要这样的性能,Python 可能不是最佳选择,在这种情况下,我会推荐 C++。您需要一种语言功能,它被称为内联函数:https://www.geeksforgeeks.org/inline-functions-cpp/

有关 Python 和内联的更多信息:Python equivalence to inline functions or macros

无论如何,我认为你在这个方向上的努力不会有任何改善。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?