"optimizing out" getattr

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Daishi  Harada

    #1

    "optimizing out" getattr

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

  • Stephen Thorne

    #2
    Re: "optimizin g out" getattr

    On 14 Sep 2005 19:46:44 -0700, Daishi Harada <daishi@gmail.c om> wrote:[color=blue]
    > Hi,
    >
    > I'd like to get the 'get2' function below to
    > perform like the 'get1' function (I've included
    > timeit.py results).[/color]

    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

    Comment

    • Peter Otten

      #3
      Re: &quot;optimizin g out&quot; getattr

      Daishi Harada wrote:
      [color=blue]
      > I'd like to get the 'get2' function below to
      > perform like the 'get1' function (I've included
      > timeit.py results).[/color]
      [color=blue]
      > 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[/color]
      [color=blue]
      > I'm not sure how to write 'mkget' to do achieve
      > this, however, except to use 'exec' - is that what
      > would be necessary?[/color]

      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.attrge tter("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

      Comment

      • Kent Johnson

        #4
        Re: &quot;optimizin g out&quot; getattr

        Peter Otten wrote:[color=blue]
        > Daishi Harada wrote:
        >
        >[color=green]
        >>I'd like to get the 'get2' function below to
        >>perform like the 'get1' function (I've included
        >>timeit.py results).[/color]
        >
        >
        >[color=green]
        >>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[/color]
        >
        > 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.attrge tter("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[/color]

        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.attrge tter("a")
        getB = operator.attrge tter("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

        Comment

        • Daishi  Harada

          #5
          Re: &quot;optimizin g out&quot; getattr

          Peter Otten wrote:[color=blue]
          > No, you can just sit back and wait -- for Python 2.5:[/color]

          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
          [color=blue]
          > $ cat attr_tuple25.py
          > import operator
          >
          > class A:
          > a = 1
          > b = 2
          >
          > get2 = operator.attrge tter("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[/color]

          Comment

          • jepler@unpythonic.net

            #6
            Re: &quot;optimizin g out&quot; getattr

            If you are including C extensions, why not crib 2.5's implementation of
            operator.attrge tter? It looks like it is fairly modular.

            Download Python for free. The Python programming language, an object-oriented scripting and rapid application development language. You can download it from http://www.python.org/download


            Jeff

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

            iD8DBQFDKiBEJd0 1MZaTXX0RAud7AJ 9WZWUf/BsAJR4KFALX+i5g Lq9W6wCeIoRA
            XxyI2o95VLYhsU8 B9CeH0w4=
            =8j9w
            -----END PGP SIGNATURE-----

            Comment

            Working...