Reputation: 8045
Today when I checked some code at the office, I found the following code. It shocked me.
class XXXX():
def __init__(self, k, v):
for i in range(len(k)):
setattr(self, k[i], v[i])
Then I found that most of the classes are written in the same way. That means all the classes are the same class,the only different is their name.
In this project setattr()
is used to set attributes and getattr()
is used to get attributes In profile log setattr
was called 2700 times and getattr
was called 3800 times. The time consume was 0.003sec and 0.005sec respectively (whole process: 0.069sec).
Though I do think setattr
and getattr
drag down the speed, I'm not sure if a rewrite of all the code would make it better.
Does obj.attribute = value run faster than setattr(obj,'attribute',value)
?
Upvotes: 7
Views: 7074
Reputation: 840
I did a small test. It was roughly 2x slower.
Increment using member took 2.8221039772
Increment using attr took 5.94811701775
Here is my code
import timeit
class Dummy(object):
__slots__ = ['testVal']
def __init__(self):
self.testVal = 0
def increment_using_attr(self):
i = getattr(self, 'testVal')
setattr(self, 'testVal', i+1)
def increment(self):
self.testVal += 1
if __name__ == '__main__':
d = Dummy()
print "Increment using member took {0}".format(timeit.Timer(d.increment).timeit(10000000))
print "Increment using attr took {0}".format(timeit.Timer(d.increment_using_attr).timeit(10000000))
Run on machine Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
Upvotes: 3
Reputation: 69298
Yes, getattr
and setattr
are much slower, at least at the CPU level.
Since __init__
is only called once per object I wouldn't worry about that unless you are creating many, many objects.
If the objects' attributes are accessed many times it could be worth it to rewrite those sections. You should do some careful profiling first, though.
Upvotes: 3