[Python-Dev] Retrieve an arbitrary element from a set without removing it (original) (raw)
Steven D'Aprano steve at pearwood.info
Sat Oct 24 00:44:22 CEST 2009
- Previous message: [Python-Dev] Retrieve an arbitrary element from a set without removing it
- Next message: [Python-Dev] Retrieve an arbitrary element from a set without removing it
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Sat, 24 Oct 2009 07:11:57 am John Arbash Meinel wrote:
The point of my test was that it was a set with a single item, and 'break' was 30% faster than 'pass'. Which was surprising.
Not really. See below.
Certainly the difference is huge if there are 10k items in the set.
Earlier you suggested that the difference may have been because of a potential "else" statement. That won't be it: if there's no "else" in the code, it's not compiled in:
import dis dis.dis(compile("for x in s: break", "", "exec")) 1 0 SETUP_LOOP 15 (to 18) 3 LOAD_NAME 0 (s) 6 GET_ITER 7 FOR_ITER 7 (to 17) 10 STORE_NAME 1 (x) 13 BREAK_LOOP 14 JUMP_ABSOLUTE 7 17 POP_BLOCK 18 LOAD_CONST 0 (None) 21 RETURN_VALUE
dis.dis(compile("for x in s: pass", "", "exec")) 1 0 SETUP_LOOP 14 (to 17) 3 LOAD_NAME 0 (s) 6 GET_ITER 7 FOR_ITER 6 (to 16) 10 STORE_NAME 1 (x) 13 JUMP_ABSOLUTE 7 16 POP_BLOCK 17 LOAD_CONST 0 (None) 20 RETURN_VALUE
The difference is likely to be this:
for x in s: break
retrieves the first (only) element of the set, then immediately breaks out of the loop. This is very different from:
for x in s: pass
which retrieves the first element of the set, then tries to retrieve a second element, which fails and raises StopIteration, which is then caught, ending the loop. That's much more expensive.
-- Steven D'Aprano
- Previous message: [Python-Dev] Retrieve an arbitrary element from a set without removing it
- Next message: [Python-Dev] Retrieve an arbitrary element from a set without removing it
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]