4 ms·
The empty loop in python was surprisingly slow (68,000,000 iterations per second). What is it actually doing here? A 3ghz cpu has 3 billion cycles per second.
by ghj 6y ago
The empty loop in python was surprisingly slow (68,000,000 iterations per second).
What is it actually doing here? A 3ghz cpu has 3 billion cycles per second. So it's spending an average of 44 cycles to increment an integer and compare???
(also fun fact, python integers are 28 bytes, but it still doesn't really explain the slowness: `import sys; sys.getsizeof(123456)`)
- smallpipe 6y agoPython might have changed since this was written, but on my machine, with any number, it finishes in 0.0s! My understanding was that to access a variable, python does a dictionary lookup to match the name to a memory location, which would explain what happens with an older python.
- wwright 6y agoThat happens for global lookups, but methods should use a stack-like lookup for local variables which should be much faster IIRC (Personally, I really question the extremely-dynamic-by-default design of that generation of languages; is being able to treat globals as a dictionary occasionally worth forcing a key lookup on every single global use?)
- teraflop 6y agoI just tested this on a Linux box I happened to have running, using the "perf" tool. By my measurements, each iteration takes about 104 instructions, of which 23 are conditional branches, and completes in about 31 cycles. (That's after subtracting about 30 million cycles of startup overhead. Tested with Python 2.7.9 on an Intel i3-4160 processor.) Remember, Python is a bytecode-interpreted language. Each iteration of the loop involves multiple bytecode operations: 2 0 SETUP_LOOP 20 (to 23) 3 LOAD_GLOBAL 0 (xrange) 6 LOAD_FAST 0 (NUMBER) 9 CALL_FUNCTION 1 12 GET_ITER >> 13 FOR_ITER 6 (to 22) 16 STORE_FAST 1 (_) 3 19 JUMP_ABSOLUTE 13 >> 22 POP_BLOCK >> 23 LOAD_CONST 0 (None) 26 RETURN_VALUE Executing each of those instructions means fetching it, jumping to the implementation of the appropriate opcode, and then updating the VM's state -- or, in the case of FOR_ITER, calling the native C function that advances the iterator. Frankly, it's impressive that it's as fast as it is.
- f1refly 6y ago> tested with python 2.7.9 Oof. https://www.python.org/doc/sunset-python-2/ https://www.python.org/doc/sunset-python-2/
- heavenlyblue 6y agoPython integers are also not limited in size and you also run the overhead of the interpreter.