I'm missing something here with range vs. xrange

Carl Banks pavlovevidence at gmail.com
Sat Dec 8 01:27:59 EST 2007


On Dec 7, 4:08 pm, "Joe Goldthwaite" <j... at goldthwaites.com> wrote:
> Here's the simple benchmark;
>
> start = time.time()
> for x in xrange(3):
>         for y in xrange(10000000):
>                 pass
> print 'xRange %s' % (time.time() - start)
>
> start = time.time()
> for x in range(3):
>         for y in range(10000000):
>                 pass
> print 'Range %s' % (time.time() - start)
>
> Here's what I get;
>
> xRange 92.5529999733
> Range 95.2669999599
>
> Not a lot of difference.


Try this:

start = time.time()
for x in xrange(3):
        for y in xrange(10000000):
                if y == 10:
                        break
print 'xRange %s' % (time.time() - start)

start = time.time()
for x in range(3):
        for y in range(10000000):
                if y == 10:
                        break
print 'Range %s' % (time.time() - start)


> Range is slower but not by much. I know that range
> builds
> a list then iterates through it. I thought that xrange just kept a counter
> that was
> incremented and returned with each call. No list was ever created. If that's
> true
> (and I guess it's not), xrange would be much faster than range. It seems
> almost
> identical.

xrange doesn't merely return a counter.  It creates an int object and
returns it, which is somewhat more expensive.  The time required to
create ten million integer objects dwarfs the time required to
allocate a single list with ten million entries, and this cost occurs
with both range and xrange, unless you break early.

>  Given the amount of performance difference, I don't see why
> xrange even
> exists.

To keep memory use down.  It's pointless and wasteful to allocate
about 160 megabytes (or 1 kilobyte) of data to store a list when you
only need 36 or so of those bytes at any given time.



Carl Banks



More information about the Python-list mailing list