1

I am using Python 2.7.5 on CentOS 7 now. And I am trying to see the performance difference among generator, list.append and list comprehension. Here is my block of code:

import timeit
import random


def generate(num):
    for _ in xrange(num):
        yield random.randrange(10)


def create_list1(num):
    numbers = []
    for _ in xrange(num):
        numbers.append(random.randrange(10))
    return numbers


def create_list2(num):
    return [random.randrange(10) for _ in xrange(num)]


if __name__ == '__main__':
    print(timeit.timeit(
        'sum(generate(999999))', setup='from __main__ import generate',
        number=1))  # >>> 0.649271011353
    print(timeit.timeit(
        'sum(create_list1(999999))', setup='from __main__ import create_list1',
        number=1))  # >>> 0.667152881622
    print(timeit.timeit(
        'sum(create_list2(999999))', setup='from __main__ import create_list2',
        number=1))  # >>> 0.590311050415

I have run this several times and the trend is similar. create_list1 > generate > create_list2.

So I found some question here with good explanations why list comprehension could "possibly" out-perform generator in python 2. But what does

In Python 2 you are not going to get any additional line for a list comprehension(LC) because LC are not creating any object, but in Python 3 you will because now to make it similar to a generator expression an additional code object() is created for a LC as well.

actually mean? Does that give us a list? And why list comprehension is like the "better version"?

Community
  • 1
  • 1
Junchao Gu
  • 1,815
  • 6
  • 27
  • 43
  • You can call `dis.dis(myfunction)` to see the compiled python bytecodes and look at the differences. In this case, profiler isn't going to profile in-line code, just functions, and since the list is iterated in-line, you don't see it. In python3, however, list iterations are function calls (that is, python creates a code object for it) so the profiler will see it. – tdelaney Feb 15 '16 at 04:16
  • Just an observation that you're kind of fighting the language with `xrange(1, (num + 1))`, when the natural thing to use is just `xrange(num)`. Why the objection to zero-based indexing, especially when the index isn't even used? – Tom Karzes Feb 15 '16 at 04:41
  • question edited. I suppose those xrange VS while should not make a difference since random is called most frequently – Junchao Gu Feb 15 '16 at 06:27

0 Answers0