Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does setattr() and getattr() slow down the speed dramatically?

Tags:

python-3.x

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)?

like image 455
Max Avatar asked Oct 09 '12 11:10

Max


People also ask

Is Getattr slow?

Yes, compared to the direct conventional method of accessing an attribute of a given object, the performance of getattr() is slower.

What is Setattr () and Getattr () used for?

Python setattr() and getattr() goes hand-in-hand. As we have already seen what getattr() does; The setattr() function is used to assign a new value to an object/instance attribute.

What is the usage of Setattr () function?

Python setattr() function is used to assign a new value to the attribute of an object/instance. Setattr in python sets a new specified value argument to the specified attribute name of a class/function's defined object.

Why do we use Setattr () in Python?

Python setattr() function is used to set a value to the object's attribute. It takes three arguments an object, a string, and an arbitrary value, and returns none. It is helpful when we want to add a new attribute to an object and set a value to it.


2 Answers

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.

like image 98
Ethan Furman Avatar answered Oct 10 '22 11:10

Ethan Furman


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

like image 37
victtim Avatar answered Oct 10 '22 11:10

victtim