4 ms·
None of the performance tuning suggestions are benchmarked, and I find it hard to believe these would ever make a substantial difference. They could make a stat
by the_jeremy 7y ago
None of the performance tuning suggestions are benchmarked, and I find it hard to believe these would ever make a substantial difference. They could make a statistically significant difference, maybe, but local variables vs class attributes? You should show how much of a time saver this is, because I can't envision a realistic scenario where this is worth the developer time.
- iudqnolq 7y agoYes, but TFA begins with a discussion of benchmarking methods and it would just take some copy and pasting to figure out if you're right. Edit: I tested it and there is a difference I picked the example you mentioned, defined the regex constant as "s" and the line constant as "asas", increased the iteration count from 10^4 to 10^6 to make the difference more noticable (got no noticable difference w/o that change) and measured the programs with time in Termux on my Nexus 5. Real time for fast: 3.150, real time for slow: 3.623. Times average of three runs ("time python fast|slow.py"). I ran once with same setup and threw out results before the runs. Edit2: actually you mentioned a different example, my bad. I didn't measure any others because vim with a touchscreen keyboard is a PITA, no idea if the one you referring is true.
- iudqnolq 7y agoEdit3: times in seconds
- kragen 7y agoThe runtime cost of instance attribute access rather than local variable access can account for a quarter of a program’s run time; I just tried it on my phone: Python 3.7.4 (default, Jul 28 2019, 22:33:35) Type 'copyright', 'credits' or 'license' for more information IPython 7.8.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: class X: ...: def y(z): ...: return z.a + z.a + z.a + z.a + z.a ...: def w(z): ...: a = z.a ...: return a+a+a+a+a ...: In [2]: x = X() In [3]: x.a = 3 In [4]: x.y() Out[4]: 15 In [5]: x.w() Out[5]: 15 In [6]: %timeit x.y() 1.7 µs ± 11.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [7]: %timeit x.w() 1.11 µs ± 5.95 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) This is often surprising to novices in Python, but attribute access involves a hash table lookup. Note that here we are comparing two instance attribute accesses against seven, not zero against five. Evidently each of them cost about 118 ns, so if we could reduce them to zero, the method call and return and four additions would cost only 870 ns, which is closer to half the runtime than ¾. Moral: benchmark before pooh-poohing a hotspot. Also though note that several thousand instructions is a pretty heavy price to pay for four integer additions.
- maksimum 7y agoCompared to __slots__ (also Python 3.7.4) Using your definition of class X %timeit x.w() 313 ns ± 18.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) Add __slots__ class X: __slots__ = ('a') def w(z): a = z.a return a+a+a+a+a %timeit x.w() 271 ns ± 7.13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) About 14% less time.
- kragen 7y agoYour computer is evidently faster than my phone; how fast was y() for you? Also you are missing a comma in your would-be tuple.
- Dylan16807 7y agoFor what it's worth I got about 196 and 131 for the original y and w, and after adding __slots__ (with comma) I got 186 and 123.
- kragen 7y agoThe fact that the difference is 10ms and 8ms respectively suggests that the speedup of attribute access isn't what's showing up in your measurements. In one case we access the slot "a" once; in the other case we access it five times. How can that be a 20% difference?
- Sean1708 7y ago> can account for a quarter of a program’s run time It can but it will more likely account for much much less than that, unless all your programs are massive loops that do little more than access the same attribute repeatedly.
- lmeyerov 7y agoMaybe coming from a diff place? It seemed fair: I spent an hour or two today basically undoing some canonical high-level Python/Pandas abstractions into canonical numpy+C, which was exactly this kind of stuff. We normally do GPU offloading (rapids.ai / blazingsql), though today's kernel was the uncomfortable inbetween where latency mattered but the task is too small for the offloading communication hit. We do the same kind of stuff (and a bit cleaner / more predictable) in JS with typed arrays. I wouldn't call that blazingly fast python though, that's barely approaching C, which is also slow. Fast is maxing out SIMD + cores + GPUs + bandwidth, so should aim for ~20X+ faster than regular C...
- jve 7y agoYeah, that annoys. Shows many optimization techniques, doesn't even apply them to original problem and presents no benchmark. You can't even know if you are dealing with micro-optimization or getting any evidence that stuff like that helps.