首页 > 解决方案 > 如何/为什么通过将类属性复制到局部变量来优化代码?

问题描述

我有一个运行数值模拟的函数。主函数的输入太多了,我创建了一个类(没有方法)来存储它们,比如:

myinput=MyInput()
myinput.file1 = file1
myinput.file2 = file2
myinput.something = something
run_model(myinput)

我在想优化代码的一种方法是创建局部变量,以便作为程序一部分的许多函数读取局部变量,而无需访问 MyInput 类的对象。这是因为这些变量中的大多数都需要多次访问,我想访问 classinstance.attribute 而不是 localvariable 是有代价的。例如:

def myfun(myinput):
    something=myinput.something
    step1=fun1(something)
    step2=fun2(something)
    out=something + step1 + step2

这种推理方式正确吗? 我已经用下面的代码对其进行了测试,我看到了大约 30% 的改进。有没有其他方法可以改善它?这是可以预料的吗?在开始重构我的所有代码之前,我想了解它背后的理论。

为什么访问 myclass.attributes 在性能方面如此昂贵?这是 Python 的限制还是其他语言也有这种情况?

import timeit

class MyClass:
    def __init__(self,a,b,c,d,e):
        self.a=a
        self.b=b
        self.c=c
        self.d=d
        self.e=e

def fun_local(myclass, size):
    a=myclass.a
    b=myclass.b
    c=myclass.c
    d=myclass.d
    e=myclass.e

    for i in range(size):
        x = (a+b)**c+d*e

def fun(myclass, size):
    for i in range(size):
        x= (myclass.a + myclass.b)** myclass.c + myclass.d * myclass.e

myclass=MyClass(8,4,4,10,100)
rep=3
num=10
size=int(1e6)
res_local = min( timeit.Timer( "fun_local(myclass, size)", globals=globals() ).repeat(repeat= rep, number = num )   )
res_noloc = min( timeit.Timer( "fun(myclass, size)", globals=globals() ).repeat(repeat= rep, number = num )   )

标签: pythonoopoptimization

解决方案


推荐阅读