4 ms·
I had the same problem: of course an empty loop will run at the maximum because any worthwhile compiler would optimize the loop away.
by radicalbyte 11y ago
I had the same problem: of course an empty loop will run at the maximum because any worthwhile compiler would optimize the loop away.
- logicallee 11y agoThe real head-scratcher is why the Python version, whose loop is: def f(NUMBER): for _ in xrange(NUMBER): pass runs one tenth as fast! Is it due to the xrange construct? I'm sure that there must be a saner way to make a loop in Python that doesn't bloat to ten times as many cycles as in C. . .
- reubenmorais 11y ago10x is about what you'd expect for the interpreter overhead in a simple snippet like that.
- andreasvc 11y agoSpecifically, an interpreter without JIT. I'd reckon that LuaJIT or Javascript could come much closer to C.
- reubenmorais 11y agoRight, those are usually called JIT compilers, not interpreters.
- andreasvc 11y agoThe distinction is not all that useful, and is blurred nowadays. You could say that CPython compiles code to bytecode, but the bytecode is then interpreted; however, none of that matters, because it's doing very little optimization and that means it's slow. Javascript is typically also not compiled ahead-of-time to native code, but it can still be very fast because of JIT; at the same time it's still very much a dynamic language which makes it share features with interpreted languages. I'd say JIT is neither about compilation nor interpretation, but about optimization.
- deleted 11y ago[deleted]
- warbiscuit 11y agoFor me, running their sample script using the PyPy JIT resulted in a 12x speedup compared to cpython. Though that still wasn't as fast as gcc on my system (core i5 3.4ghz; using 1e8 rounds): * cpython 2.7.4 - 1.131s * pypy 2.6.0 - 0.090s * gcc w/ "-O2" - 0.050s
- cma 11y agoUnfortunately python doesn't use a tagged pointers optimization even though I believe pointers are always aligned so there are some spare bits that could be used to indicate pointer vs. int. I think the only reason they haven't is the legacy C interface; it's a shame they didn't do it for Python 3, but I guess it could have delayed conversion of c libraries even more.
- ProblemFactory 11y agoIt runs at 1/10 speed because it's interpreted bytecode, and it allocates a new PyInt object for each number in the loop. You can get it back close to native speed by adding a type annotation and compiling the python file with Cython: http://docs.cython.org/src/userguide/language_basics.html#integer-for-loops http://docs.cython.org/src/userguide/language_basics.html#in... def f(NUMBER): cdef int i for i in range(NUMBER): pass
- andreasvc 11y agoNot just close to native speed, this will get you the exact same C code for the inner loop.
- mulander 11y agoI wonder if [x for x in xrange(NUMBER)] would be any faster. Yes it allocates an array but list comprehension is executed differently by python. I recall a talk by some Dropbox guy stating that it was one of their optimization strategies. Didn't find the original talk but found this: https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Loops https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Loo...
- andreasvc 11y agoNitpick: that creates a list, not an array. It could be faster, but it's not the same benchmark. When you get to the point where the speed of loops matters it's better to reach for Cython, Numba, PyPy, etc.
- dalke 11y agoWhy wonder when you can test? % python -mtimeit '[x for x in xrange(1000)]' 10000 loops, best of 3: 70.2 usec per loop % python -mtimeit 'for x in xrange(1000): pass' 10000 loops, best of 3: 29 usec per loop % python -mtimeit '[x for x in xrange(100000)]' 100 loops, best of 3: 7.03 msec per loop % python -mtimeit 'for x in xrange(100000): pass' 100 loops, best of 3: 2.5 msec per loop