Python @property versus method performance - which one to use?

后端 未结 6 1394
孤独总比滥情好
孤独总比滥情好 2021-01-04 03:31

I have written some code that uses attributes of an object:

class Foo:
    def __init__(self):
        self.bar = \"baz\"
myFoo = Foo()
print (myFoo.bar)


        
相关标签:
6条回答
  • 2021-01-04 04:09

    That's exactly what @property is meant for.

    0 讨论(0)
  • 2021-01-04 04:10

    In cases like these, I find it much better to choose the option that makes the most sense. You won't get any noticeable performance loss with small differences like these. It's much more important that your code is easy to use and maintain.

    As for choosing between using a method and a @property, it's a matter of taste, but since properties disguise themselves as simple attributes, nothing elaborate should be going on. A method indicates that it might be an expensive operation, and developers using your code will consider caching the value rather than fetching it again and again.

    So again, don't go on performance, always consider maintainability vs. performance. Computers get faster and faster as time goes by. The same does not stand for the readability of code.

    In short, if you want to get a simple calculated value, @property is an excellent choice; if you want an elaborate value calculated, a method indicates that better.

    0 讨论(0)
  • 2021-01-04 04:12

    Wondering about performance is needless when it's so easy to measure it:

    $ python -mtimeit -s'class X(object):
    >   @property
    >   def y(self): return 23
    > x=X()' 'x.y'
    1000000 loops, best of 3: 0.685 usec per loop
    $ python -mtimeit -s'class X(object):
    
      def y(self): return 23
    x=X()' 'x.y()'
    1000000 loops, best of 3: 0.447 usec per loop
    $ 
    

    (on my slow laptop -- if you wonder why the 2nd case doesn't have secondary shell prompts, it's because I built it from the first with an up-arrow in bash, and that repeats the linebreak structure but not the prompts!-).

    So unless you're in a case where you know 200+ nanoseconds or so will matter (a tight inner loop you're trying to optimize to the utmost), you can afford to use the property approach; if you do some computations to get the value, the 200+ nanoseconds will of course become a smaller fraction of the total time taken.

    I do agree with other answers that if the computations become too heavy, or you may ever want parameters, etc, a method is preferable -- similarly, I'll add, if you ever need to stash the callable somewhere but only call it later, and other fancy functional programming tricks; but I wanted to make the performance point quantitatively, since timeit makes such measurements so easy!-)

    0 讨论(0)
  • 2021-01-04 04:12

    I agree with what most people here have said, I did much measurement when building hydrologic models in Python a couple years ago and found that the speed hit from using @property was completely overshadowed by calculation.

    As an example, creating method local variables (removing the "dot factor" in my calculations increased performance by almost an order of magnitude more than removing @property (these results are averaged over a mid-scale application).

    I'd look elsewhere for optimization, when it's necessary, and focus initially on getting good, maintainable code written. At this point, if @property is intuitive in your case, use it. If not, make a method.

    0 讨论(0)
  • 2021-01-04 04:23

    If it's logically a property/attribute of the object, I'd say keep it as a property. If it's likely to become parametrised, by which I mean you may want to invoke myFoo.bar(someArgs) then bite the bullet now and make it a method.

    Under most circumstances, performance is unlikely to be an issue.

    0 讨论(0)
  • 2021-01-04 04:29

    I would go for the refactoring, but only for a matter of style - it seems clearer to me that "fancy calculations" might be ongoing with a method call, while I would expect a property to be almost a no-op, but this is a matter of taste.

    Don't worry about the decorator's performance... if you think that it might be a problem, measure the performance in both cases and see how much it does add (my guess is that it will be totally negligible if compared to your fancy calculations).

    0 讨论(0)
提交回复
热议问题