By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,100 Members | 2,892 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,100 IT Pros & Developers. It's quick & easy.

Speed up properties?!

P: n/a
Hi,

I have a class with some properties. I would like to verify that only
valid values are assigned to the properties using assert. Therefore I
code setters and getters and use property() to convert these to have a
real property.

Since the verification is only performed in __debug__ runs the
property() is quite a lot of overhead. I tried to circumvent it. This
is my result so far:
class C(object):
def __init__(self):
self._x = 5
if not __debug__:
self.x = property(self._x, self._x)

def getX(self):
return self._x

def setX(self, v):
assert 0 <= v <= 5
self._x = v

if __debug__:
x = property(getX, setX)

o = C()
def test():
o.x

if __name__=='__main__':
from timeit import Timer
t = Timer("test()", "from __main__ import test")
print t.timeit()

As you can see, in non __debug__ runs the accesses of the x property do
not result in calls to getX or setX. There I can get a speedup of 2!
But to be honest: I don't like this aproach. So is there some better,
cleaner way?

Peer


Jul 18 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Dr. Peer Griebel wrote:
I have a class with some properties. I would like to verify that only
valid values are assigned to the properties using assert. Therefore I
code setters and getters and use property() to convert these to have a
real property.

Since the verification is only performed in __debug__ runs the
property() is quite a lot of overhead. I tried to circumvent it. This
is my result so far:
class C(object):
def __init__(self):
self._x = 5
if not __debug__:
self.x = property(self._x, self._x)

def getX(self):
return self._x

def setX(self, v):
assert 0 <= v <= 5
self._x = v

if __debug__:
x = property(getX, setX)

o = C()
def test():
o.x

if __name__=='__main__':
from timeit import Timer
t = Timer("test()", "from __main__ import test")
print t.timeit()

As you can see, in non __debug__ runs the accesses of the x property do
not result in calls to getX or setX. There I can get a speedup of 2!
But to be honest: I don't like this aproach. So is there some better,
cleaner way?


class C(object):
def __init__(self):
self.setX(5)

def setX(self, x):
if not 0 <= x <= 5:
raise ValueError
self.x = x

# for speed comparison only:
y = property(lambda s: s.x)

o = C()

With the above, my timings show an even greater speed difference:

$ timeit.py -s'from propspeed import o' 'o.x'
1000000 loops, best of 3: 0.235 usec per loop
$ timeit.py -s'from propspeed import o' 'o.y'
1000000 loops, best of 3: 1.04 usec per loop

Special debug code is dangerous because it can hide errors in the final
version. So, if speed is that important and read access paramount, go for
the asymmetric solution and use o.x for read access and o.setX() - always
checked - for write access.
However, my guess is that in most cases you will hardly feel any impact on
the overall speed of your program, and in that case I'd recommend an x
property - again with the value check preserved in the non-debug version.
If you then encounter a performance problem, you probably can pin it down to
some inner loop, and replacing o.x with o._x (only) there should be
painless.

Peter
Jul 18 '05 #2

P: n/a
On Fri, 14 May 2004 08:53:30 +0200, in comp.lang.python Peter Otten
wrote:

[comparing direct attribute access and indirect through property get]

A slight addition to your code for another alternative (2.4 only) of
property gets (the z property):

class C(object):
def __init__(self):
self.setX(5)

def setX(self, x):
if not 0 <= x <= 5:
raise ValueError
self.x = x

# for speed comparison only:
y = property(lambda s: s.x)

from operator import attrgetter
z = property(attrgetter("x"))

o = C()

yields (on my laptop):

C:\Temp>timeit -s "from propspeed import o" o.x
1000000 loops, best of 3: 0.655 usec per loop

C:\Temp>timeit -s "from propspeed import o" o.y
100000 loops, best of 3: 2.36 usec per loop

C:\Temp>timeit -s "from propspeed import o" o.z
1000000 loops, best of 3: 1.51 usec per loop
--
TZOTZIOY, I speak England very best,
Ils sont fous ces Redmontains! --Harddix
Jul 18 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.