preferring [] or () in list of error codes?

John Machin sjmachin at lexicon.net
Tue Jun 9 01:28:42 CEST 2009


 <mh <at> pixar.com> writes:

> 
> Is there any reason to prefer one or the other of these statements?
> 
>         if e.message.code in [25401,25402,25408]:
>         if e.message.code in (25401,25402,25408):
> 

>From the viewpoint of relative execution speed, in the above case
if it matters at all it matters only on Python 2.4 AFAICT:

| >>> L=lambda x:x in[25401,25402,25408];
T=lambda x:x in(25401,25402,25408);import dis;dis.dis(L);dis.dis(T)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (25401)
              6 LOAD_CONST               2 (25402)
              9 LOAD_CONST               3 (25408)
             12 BUILD_LIST               3
             15 COMPARE_OP               6 (in)
             18 RETURN_VALUE
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               4 ((25401, 25402, 25408))
              6 COMPARE_OP               6 (in)
              9 RETURN_VALUE

Earlier versions build the list or tuple at run time
(as for the list above); later versions detect that
the list can't be mutated and generate the same code
for both the list and tuple.

However there are limits to the analysis that can be
performed e.g. if the list is passed to a function,
pursuit halts at the county line:

[Python 2.6.2]
| >>> F=lambda y,z:y in z;L=lambda x:F(x,[25401,25402,25408]);
T=lambda x:F(x,(25401,25402,25408));import dis;dis.dis(L);dis.dis(T)
  1           0 LOAD_GLOBAL              0 (F)
              3 LOAD_FAST                0 (x)
              6 LOAD_CONST               0 (25401)
              9 LOAD_CONST               1 (25402)
             12 LOAD_CONST               2 (25408)
             15 BUILD_LIST               3
             18 CALL_FUNCTION            2
             21 RETURN_VALUE
  1           0 LOAD_GLOBAL              0 (F)
              3 LOAD_FAST                0 (x)
              6 LOAD_CONST               3 ((25401, 25402, 25408))
              9 CALL_FUNCTION            2
             12 RETURN_VALUE

So in general anywhere I had a "list constant" I'd make
it a tuple -- I'm not aware of any way that performance
gets worse by doing that, and it can get better.

Background: I'm supporting packages that run on 2.1 to 2.6
in one case and 2.4 to 2.6 in the other; every little
unobtrusive tweak helps :-)

HTH,
John




More information about the Python-list mailing list