Reputation: 94
While programming a algorithm that makes use of only using integer arithmetic I notice that Python wasn't taking advantage of it.
So I tried the following code to see the "explicitly" declaration effect
import time
repeat = 1000000
start = time.time()
x = 0
for i in range(repeat):
x += 1
no_type_time = time.time() - start
start = time.time()
y = int(0)
for i in range(repeat):
y += 1
int_time = time.time() - start
print('{} - No type'.format(no_type_time))
print('{} - Int'.format(int_time))
The code output was the following:
0.0692429542542 - No type
0.0545210838318 - Int
I assume it has something to do with Python being a dynamic typed language. But when I try to find out the type of the variables, using type(x) and type(y) both output int. Which is curious, because I also ran some tests using x = float(0) and the result is very close to the one with no type "declaration".
I'd like to know why it happens and if possible to get some reference from Python documentation explaining it.
Upvotes: 0
Views: 2166
Reputation: 280973
From the precision on the floats in your str.format
output (12 significant digits), we can see that you're probably on Python 2.
Python 2 creates an explicit list of a million ints when you run range(repeat)
, which is slow. It also keeps the memory for all of those ints, so range(repeat)
is less slow the second time. This is most likely the source of the timing difference, not anything to do with calling int
.
On Python 2, it is almost always better to use xrange
instead of range
. xrange
generates ints on demand, avoiding the cost in memory and allocation time of generating a whole list up front:
for i in xrange(repeat):
do_stuff()
Upvotes: 7
Reputation: 37539
This is happening because python caches and reuses some immutable built-in objects, even if they're "stored" as different variables
>>> a = 1
>>> id(a)
56188528L
>>> b = int(1)
>>> id(b)
56188528L
Python didn't have to allocate any memory or instantiate a new object for the second variable. It's just reusing the immutable integer object that had already been created.
If you had put your timing tests in different files and ran them separately, or if you had ran the int(1)
test first, you would have seen different results.
Upvotes: -1
Reputation: 1615
I am not able to reproduce on linux. Mark that:
• real: The actual time spent in running the process from start to finish, as if it was measured by a human with a stopwatch
• user: The cumulative time spent by all the CPUs during the computation
• sys: The cumulative time spent by all the CPUs during system-related tasks such as memory allocation.
→ time python type.py
real 0m0.219s
user 0m0.000s
sys 0m0.000s
→ time python without_type.py
real 0m0.133s
user 0m0.000s
sys 0m0.000s
Upvotes: 1