range() in Python 2 versus range() in Python 3

We run same Python code in two different Ipython/Jupyter notebooks. The code is designed to highlight the differences in how Python 2 and Python 3 do range(). The function foo, iterates through range(n), but quits the loop the first time the body of the loop is executed. So the body of the loop takes very very little time to execute. So long execution times for foo(n) are mostly the execution time of range(n).


In [1]:
n = 10**7

In [2]:
def foo(n):
    for i in range(n):
        break

In [3]:
foo(n)

In [4]:
%timeit foo(n)


1 loops, best of 3: 246 ms per loop

In [5]:
n = 10**8

In [6]:
%timeit foo(n)


1 loops, best of 3: 2.41 s per loop

In [7]:
n = 10**9

In [8]:
%timeit foo(n)


---------------------------------------------------------------------------
MemoryError                               Traceback (most recent call last)
<ipython-input-8-40e486ed36cb> in <module>()
----> 1 get_ipython().magic(u'timeit foo(n)')

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/interactiveshell.pyc in magic(self, arg_s)
   2302         magic_name, _, magic_arg_s = arg_s.partition(' ')
   2303         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-> 2304         return self.run_line_magic(magic_name, magic_arg_s)
   2305 
   2306     #-------------------------------------------------------------------------

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/interactiveshell.pyc in run_line_magic(self, magic_name, line)
   2223                 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
   2224             with self.builtin_trap:
-> 2225                 result = fn(*args,**kwargs)
   2226             return result
   2227 

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in timeit(self, line, cell)

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magic.pyc in <lambda>(f, *a, **k)
    191     # but it's overkill for just that one bit of state.
    192     def magic_deco(arg):
--> 193         call = lambda f, *a, **k: f(*a, **k)
    194 
    195         if callable(arg):

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in timeit(self, line, cell)
   1034             number = 1
   1035             for _ in range(1, 10):
-> 1036                 time_number = timer.timeit(number)
   1037                 worst_tuning = max(worst_tuning, time_number / number)
   1038                 if time_number >= 0.2:

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in timeit(self, number)
    130         gc.disable()
    131         try:
--> 132             timing = self.inner(it, self.timer)
    133         finally:
    134             if gcold:

<magic-timeit> in inner(_it, _timer)

<ipython-input-2-1eb3c73e0277> in foo(n)
      1 def foo(n):
----> 2     for i in range(n):
      3         break

MemoryError: 

In [9]:
n = 10**12345

In [10]:
%timeit foo(n)


---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-10-40e486ed36cb> in <module>()
----> 1 get_ipython().magic(u'timeit foo(n)')

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/interactiveshell.pyc in magic(self, arg_s)
   2302         magic_name, _, magic_arg_s = arg_s.partition(' ')
   2303         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-> 2304         return self.run_line_magic(magic_name, magic_arg_s)
   2305 
   2306     #-------------------------------------------------------------------------

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/interactiveshell.pyc in run_line_magic(self, magic_name, line)
   2223                 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
   2224             with self.builtin_trap:
-> 2225                 result = fn(*args,**kwargs)
   2226             return result
   2227 

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in timeit(self, line, cell)

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magic.pyc in <lambda>(f, *a, **k)
    191     # but it's overkill for just that one bit of state.
    192     def magic_deco(arg):
--> 193         call = lambda f, *a, **k: f(*a, **k)
    194 
    195         if callable(arg):

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in timeit(self, line, cell)
   1034             number = 1
   1035             for _ in range(1, 10):
-> 1036                 time_number = timer.timeit(number)
   1037                 worst_tuning = max(worst_tuning, time_number / number)
   1038                 if time_number >= 0.2:

/home/doj/i/env/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in timeit(self, number)
    130         gc.disable()
    131         try:
--> 132             timing = self.inner(it, self.timer)
    133         finally:
    134             if gcold:

<magic-timeit> in inner(_it, _timer)

<ipython-input-2-1eb3c73e0277> in foo(n)
      1 def foo(n):
----> 2     for i in range(n):
      3         break

OverflowError: range() result has too many items