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

"optimizing out" getattr

P: n/a
Hi,

I'd like to get the 'get2' function below to
perform like the 'get1' function (I've included
timeit.py results).

I'm not sure how to write 'mkget' to do achieve
this, however, except to use 'exec' - is that what
would be necessary?

Thanks in advance,
d

---
class A:
a = 1
b = 2
a = A()
labels = ('a', 'b')
def get1(x):
return (x.a, x.b)
def mkget(attrs):
def getter(x):
return tuple(getattr(x, label) for label in attrs)
return getter
get2 = mkget(labels)

# % timeit.py -s "import test" "test.get1(test.a)"
# 1000000 loops, best of 3: 0.966 usec per loop
# % timeit.py -s "import test" "test.get2(test.a)"
# 100000 loops, best of 3: 4.46 usec per loop
---

Sep 15 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
On 14 Sep 2005 19:46:44 -0700, Daishi Harada <da****@gmail.com> wrote:
Hi,

I'd like to get the 'get2' function below to
perform like the 'get1' function (I've included
timeit.py results).


Do you have profiling results that show that a significant percentage
of your programs time is being spent inside this function?

If you don't, then you're wasting your time doing unnecessery optimisation.
--
Stephen Thorne
Development Engineer
Sep 15 '05 #2

P: n/a
Daishi Harada wrote:
I'd like to get the 'get2' function below to
perform like the 'get1' function (I've included
timeit.py results). labels = ('a', 'b')
def get1(x):
return (x.a, x.b)
def mkget(attrs):
def getter(x):
return tuple(getattr(x, label) for label in attrs)
return getter
get2 = mkget(labels)

# % timeit.py -s "import test" "test.get1(test.a)"
# 1000000 loops, best of 3: 0.966 usec per loop
# % timeit.py -s "import test" "test.get2(test.a)"
# 100000 loops, best of 3: 4.46 usec per loop I'm not sure how to write 'mkget' to do achieve
this, however, except to use 'exec' - is that what
would be necessary?


No, you can just sit back and wait -- for Python 2.5:

$ cat attr_tuple25.py
import operator

class A:
a = 1
b = 2

get2 = operator.attrgetter("a", "b")

def get1(x):
return x.a, x.b

$ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get1(A)'
1000000 loops, best of 3: 0.813 usec per loop
$ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get2(A)'
1000000 loops, best of 3: 0.495 usec per loop

Time till release is not included in the timings :-)

Peter

Sep 15 '05 #3

P: n/a
Peter Otten wrote:
Daishi Harada wrote:

I'd like to get the 'get2' function below to
perform like the 'get1' function (I've included
timeit.py results).

labels = ('a', 'b')
def get1(x):
return (x.a, x.b)
def mkget(attrs):
def getter(x):
return tuple(getattr(x, label) for label in attrs)
return getter
get2 = mkget(labels)

# % timeit.py -s "import test" "test.get1(test.a)"
# 1000000 loops, best of 3: 0.966 usec per loop
# % timeit.py -s "import test" "test.get2(test.a)"
# 100000 loops, best of 3: 4.46 usec per loop


No, you can just sit back and wait -- for Python 2.5:

$ cat attr_tuple25.py
import operator

class A:
a = 1
b = 2

get2 = operator.attrgetter("a", "b")

def get1(x):
return x.a, x.b

$ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get1(A)'
1000000 loops, best of 3: 0.813 usec per loop
$ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get2(A)'
1000000 loops, best of 3: 0.495 usec per loop


With Python 2.4 you can at least get closer to the hardcoded version:

F:\>type attr_tuple.py
import operator

class A:
a = 1
b = 2

getA = operator.attrgetter("a")
getB = operator.attrgetter("b")

def get2(x):
return getA(x), getB(x)

def get1(x):
return x.a, x.b

F:\>python -m timeit -s"from attr_tuple import A, get1, get2" "get1(A)"
1000000 loops, best of 3: 0.658 usec per loop

F:\>python -m timeit -s"from attr_tuple import A, get1, get2" "get2(A)"
1000000 loops, best of 3: 1.04 usec per loop

Kent
Sep 15 '05 #4

P: n/a
Peter Otten wrote:
No, you can just sit back and wait -- for Python 2.5:
Thanks for the tip;
Although for my current use
I can't target 2.5, I hadn't even
noticed the attr/itemgetter
additions to operator in 2.4,
so I appreciate the pointer
for future reference.
d
$ cat attr_tuple25.py
import operator

class A:
a = 1
b = 2

get2 = operator.attrgetter("a", "b")

def get1(x):
return x.a, x.b

$ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get1(A)'
1000000 loops, best of 3: 0.813 usec per loop
$ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get2(A)'
1000000 loops, best of 3: 0.495 usec per loop

Time till release is not included in the timings :-)

Peter


Sep 16 '05 #5

P: n/a
If you are including C extensions, why not crib 2.5's implementation of
operator.attrgetter? It looks like it is fairly modular.

http://cvs.sourceforge.net/viewcvs.p...les/operator.c

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFDKiBEJd01MZaTXX0RAud7AJ9WZWUf/BsAJR4KFALX+i5gLq9W6wCeIoRA
XxyI2o95VLYhsU8B9CeH0w4=
=8j9w
-----END PGP SIGNATURE-----

Sep 16 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.