5
votes

Why does

sys.getrefcount() 

return 3 for every large number or simple string?Does that mean that 3 objects reside somewhere in the Program?Also,why doesn't setting x=(very large number) increase that object's ref count?Do those 3 ref counts result from my call to getrefcount? Thank you for clarifying this.

for instance:

>>> sys.getrefcount(4234234555)
3
>>> sys.getrefcount("testing")
3
>>> sys.getrefcount(11111111111111111)
3
>>> x=11111111111111111
>>> sys.getrefcount(11111111111111111)
3 
3
Although x="testing" increases the ref count,x=(large number) doesn't. - kaiseroskilo

3 Answers

10
votes

Large integer objects are not reused by the interpretor, so you get two distinct objects:

>>> a = 11111
>>> b = 11111
>>> id(a)
40351656
>>> id(b)
40351704

sys.getrefcount(11111) always returns the same number because it measures the reference count of a fresh object.

For small integers, Python always reuses the same object:

>>> sys.getrefcount(1)
73

Usually you would get only one reference to a new object:

>>> sys.getrefcount(object())
1

But integers are allocated in a special pre-malloced area by Python for performance optimization, and I suspect the extra two references have something to do with this.

You can look at the C implementation here: http://svn.python.org/view/python/trunk/Objects/intobject.c?view=markup

Edit: I do not claim to understand what's going on in lowlevel details, I think there are several things at work that cache temporary references:

print sys.getrefcount('foo1111111111111' + 'bar1111111111111') #1
print sys.getrefcount(111111111111 + 2222222222222)            #2
print sys.getrefcount('foobar333333333333333333')              #3
6
votes
  1. Small strings and integers are cached by Python to save on object construction cost.

  2. The interactive Python interpreter holds a temporary reference to each literal that you enter. Compare getrefcount('foobar') with getrefcount('foo' + 'bar'). (In the latter case, the interpreter has references to 'foo' and 'bar'.)

  3. From the manual:

The count returned is generally one higher than you might expect, because it includes the (temporary) reference as an argument to getrefcount().

1
votes

It seems that when you pass a direct number as an argument to sys.getrefcount, you have 3 references:

  • 1 for the object itself (logical);
  • 1 (temporary) for the object passed as argument to sys.getrefcount;
  • and I would suppose 1 (temporary) for the interpreter, which I suppose converts the raw number (or string, or anything else) into an interpretable object.

For instance, let's consider this:

>>> sys.getrefcount(123456)
3

>>> a = 123456
>>> sys.getrefcount(a)
2

I don't really know what happens in the mind of Python, but it is interesting nonetheless. I can only guess the raw integer (ref #1) is temporarily converted into an int object (ref #2), which is then passed as an argument to sys.getrefcount (ref #3).