http://www.laurentluce.com/posts/python-integer-objects-implementation/
Python integer Objects implementationmay 15, 2011
This article describes how integer objects is managed by Python internally.
An integer object in Python was represented internally by the structure Pyintobject. Its value was an attribute of type long.
To avoid allocating a new integer object each time a new integer object was needed, Python allocates a block of free unused Integer objects in advance.
The following structure is used by Python to allocate integer objects, also called Pyintobjects. Once This structure is initialized, the integer objects was ready for used when new integer values was assigned to OBJEC TS in a Python script. This structure are called "Pyintblock" and is defined as:
3 |
PyIntObject objects[N_INTOBJECTS]; |
5 |
typedefstruct_intblock PyIntBlock; |
When a block of an integer objects is allocated by Python, the objects has no value assigned to them yet. We call them free integer objects ready to be used. A value would be assigned to the next free object when a new integer value was used in your. No memory allocation would be required if a free integer object ' s value was set so it would be fast.
The integer objects inside the block is linked together back to front using their internal pointer called Ob_type. As noted in the source code, this is a abuse of this internal pointer so does not pay too much attention to the name.
Each block of integers contains the number of an integer objects which can fit in a block of 1K bytes, about + pyintobject O Bjects on my 64-bit machine. When all the integers objects inside a block is used, a new block was allocated with a new list of integer objects Availabl E.
A singly-linked list is used-keep track of the integers blocks allocated. It is called "Block_list" internally.
A specific structure is used to refer small integers and share them so access is fast. It is a array of 262 pointers to integer objects. Those integer objects is allocated during initialization in a block of integer objects we saw above. The small integers range is from-5 to 256. Many Python programs spend a lot of time using the integers in that range so the is a smart decision.
1 |
#define NSMALLPOSINTS 257 |
2 |
#define NSMALLNEGINTS 5 |
3 |
staticPyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS]; |
The integer object representing the integer-5 is at the offset 0 inside the small integers array. The integers object representing-4 is at offset 1 ...
What happens if an integer was defined in a Python script like this one?
When you execute the first line, the function Pyint_fromlong are called and its logic is the following:
1 |
if integer value in range -5,256: |
2 |
return the integer object pointed by the small integers array at the |
5 |
if no free integer object available: |
6 |
allocate new block of integer objects |
7 |
set value of the next free integer object in the current block |
With our Example:integer 1 object are pointed by the small integers arrays at offset:1+5 = 6. A pointer to this integer object would be returned and the variable "a" would be being pointing to that integer object.
Let's a look at a different example:
View Source print?
The range of the small integers array so the next free integer object ' s value are set to 300.
If you take a look at the file intobject.c in the Python 2.6 source code, you'll see a long list of functions taking car E of operations like addition, multiplication, conversion ... The comparison function looks like this:
2 |
int_compare(PyIntObject *v, PyIntObject *w) |
4 |
registerlongi = v->ob_ival; |
5 |
registerlongj = w->ob_ival; |
6 |
return(i < j) ? -1 : (i > j) ? 1 : 0; |
The value of an integer object was stored in it ob_ival attribute which is of type long. Each of the placed in a registers to optimize access and the comparison are done between those 2 registers. -1 is returned if the integer objects pointed by V are less than the one pointed by W. 1 are returned for the opposite and 0 is returned if they is equal.
That's it for now. I hope you enjoyed the article. Please write a comment if you had any feedback.
Python Integer Objects implementation