[Chandler-dev] Harmful usage of len()
D John Anderson
john at osafoundation.org
Wed Jun 6 10:06:14 PDT 2007
Is it ever the case that __nonzero__ would return a value inconstant
from using __len__ so using it instead of len would cause a bug?
John
On Jun 5, 2007, at 10:00 PM, Heikki Toivonen wrote:
> There are lots and lots of cases in our code where we use len() to
> determine if a collection, list, tuple, string etc. is empty or not.
> This is wasteful; it is much better to check if the item in
> question is
> empty. Python even has a special method for it, __nonzero__.
>
> Also, doing a len() on some objects causes side effects to happen that
> you may not want, like creating repository indexes (of course avoiding
> index creation in one spot will likely just move it to another spot
> which you may not want).
>
> Any time you see one of these used to get a truth value, you may be
> looking at a bug:
>
> len(...)
> len(...) == 0
> len(...) != 0
> len(...) > 0
>
> What you may want to do instead is just check if the thing marked with
> ... evaluates to True. For example:
>
> if mylist:
>
> In some cases you have a function/method returning a truth value:
>
> def isEmpty(self):
> return bool(self.myList)
>
> although if you see something like above you might want to do some
> refactoring as well to get rid of that method.
>
> This holds at least for builtin lists, tuples, dicts and strings. It
> should also hold for Chandler Collection Items.
>
> Below are some timeit runs to compare list, string, dict and tuple
> performance:
>
> heikki at xanadu:~$ python -m timeit "a=[]" "if len(a)>0:pass"
> 10000000 loops, best of 3: 0.163 usec per loop
> heikki at xanadu:~$ python -m timeit "a=[]" "if len(a):pass"
> 10000000 loops, best of 3: 0.164 usec per loop
> heikki at xanadu:~$ python -m timeit "a=[]" "if a:pass"
> 10000000 loops, best of 3: 0.0892 usec per loop
>
> heikki at xanadu:~$ python -m timeit "a=[1,2,3,4]" "if len(a)>0:pass"
> 1000000 loops, best of 3: 0.328 usec per loop
> heikki at xanadu:~$ python -m timeit "a=[1,2,3,4]" "if len(a):pass"
> 1000000 loops, best of 3: 0.3 usec per loop
> heikki at xanadu:~$ python -m timeit "a=[1,2,3,4]" "if a:pass"
> 1000000 loops, best of 3: 0.242 usec per loop
>
> heikki at xanadu:~$ python -m timeit "a=''" "if len(a)>0:pass"
> 10000000 loops, best of 3: 0.18 usec per loop
> heikki at xanadu:~$ python -m timeit "a=''" "if len(a):pass"
> 10000000 loops, best of 3: 0.13 usec per loop
> heikki at xanadu:~$ python -m timeit "a=''" "if a:pass"
> 10000000 loops, best of 3: 0.0635 usec per loop
>
> heikki at xanadu:~$ python -m timeit "a='abcd'" "if len(a)>0:pass"
> 10000000 loops, best of 3: 0.136 usec per loop
> heikki at xanadu:~$ python -m timeit "a='abcd'" "if len(a):pass"
> 10000000 loops, best of 3: 0.129 usec per loop
> heikki at xanadu:~$ python -m timeit "a='abcd'" "if a:pass"
> 10000000 loops, best of 3: 0.0623 usec per loop
>
> heikki at xanadu:~$ python -m timeit "a={}" "if len(a)>0:pass"
> 10000000 loops, best of 3: 0.163 usec per loop
> heikki at xanadu:~$ python -m timeit "a={}" "if a:pass"
> 10000000 loops, best of 3: 0.0903 usec per loop
>
> heikki at xanadu:~$ python -m timeit "a=tuple()" "if len(a)>0:pass"
> 1000000 loops, best of 3: 0.253 usec per loop
> heikki at xanadu:~$ python -m timeit "a=tuple()" "if a:pass"
> 10000000 loops, best of 3: 0.177 usec per loop
>
> --
> Heikki Toivonen
>
>
>
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
>
> Open Source Applications Foundation "chandler-dev" mailing list
> http://lists.osafoundation.org/mailman/listinfo/chandler-dev
More information about the chandler-dev
mailing list