> Alternatively: do you know how much your computer could do in a second, but isn't, because the majority of software is so full of inefficiency?
Amusingly, in the first example, the compiler's static analysis concludes that the entire for loop can be omitted. I have no idea how they came up with that precise number...
Presumably they passed flags to gcc (or whichever compiler they used) to disable these optimizations, otherwise, you're right, they wouldn't make much sense if the code wasn't actually being run as presented.
Interestingly, there's quite a bit that's needed to ensure you bypass some compiler optimizations. Here's an ey-opening (for me) talk[1] on benchmarking C++ and compilers which touched on it.
The 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. . .
I 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.
Nitpick: 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.
% 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
Unfortunately 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.
The 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.
Amusingly, in the first example, the compiler's static analysis concludes that the entire for loop can be omitted. I have no idea how they came up with that precise number...