1

I have a function which runs a numerical simulation. The inputs to the main function are so many that I have created a class (with no methods) to store them all, something like:

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

I was thinking that one way to optimise the code is to create local variables so that the many functions which are part of the program read the local variables without needing to access the objects of the MyInput class. This is because most of these variables need to be accessed multiple times, and I imagine there is a cost to accessing classinstance.attribute instead of localvariable. E.g.:

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

Is this line of reasoning correct? I have tested it with the code below, and I see an improvement of about 30%. Is there another way to improve it? Is this to be expected? Before I embark on refactoring all my code, I'd like to understand the theory behind it.

Why is accessing myclass.attributes so costly in terms of performance? Is it a limitation of Python or is this common to other languages, too?

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 )   )
Pythonista anonymous
  • 8,140
  • 20
  • 70
  • 112
  • It's quicker because binding a value to a local variable means it will be found more quickly — the lookup process can be very time consuming, so if you create a name that's stored in the first place checked, it'll be found faster. See [Short description of the scoping rules?](https://stackoverflow.com/questions/291978/short-description-of-the-scoping-rules). – martineau Mar 19 '19 at 23:17
  • Thanks. Would I see a similar 30% speed improvement in languages like C# or C++? – Pythonista anonymous Mar 20 '19 at 00:01
  • 2
    Don't know about C# (but doubt it), and definitely not in C++. Compiled coded isn't doing variable name lookups at runtime. – martineau Mar 20 '19 at 00:15

0 Answers0