5

Is it possible to make Python use less than 12 bytes for an int?

>>> x=int()
>>> x
0
>>> sys.getsizeof(x)
12

I am not a computer specialist but isn't 12 bytes excessive?

The smallest int I want to store is 0, the largest int 147097614, so I shouldn't really need more than 4 bytes.

(There is probably something I misunderstand here as I couldn't find an answer anywhere on the net. Keep that in mind.)

The Unfun Cat
  • 29,987
  • 31
  • 114
  • 156

3 Answers3

11

In python, ints are objects just like everything else. Because of that, there is a little extra overhead just associated with the fact that you're using an object which has some associated meta-data.

If you're going to use lots of ints, and it makes sense to lay them out in an array-like structure, you should look into numpy. Numpy ndarray objects will have a little overhead associated with them for the various pieces of meta-data that the array objects keep track of, but the actual data is stored as the datatype you specify (e.g. numpy.int32 for a 4-byte integer.)

Thus, if you have:

import numpy as np
a = np.zeros(5000,dtype=np.int32)

The array will take only slightly more than 4*5000 = 20000 bytes of your memory

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 5
    A good answer; note that it's not necessary to depend on numpy to efficiently store a large amount of integers. The `array` module offers a lightweight (but less featureful) alternative and is available in the standard library. – user4815162342 Nov 15 '12 at 17:06
7

Size of an integer object includes the overhead of maintaining other object information along with its value. The additional information can include object type, reference count and other implementation-specific details.

If you store many integers and want to optimize the space spent, use the array module, specifically arrays constructed with array.array('i').

user4815162342
  • 141,790
  • 18
  • 296
  • 355
5

Integers in python are objects, and are therefore stored with extra overhead.

You can read more information about it here

The integer type in cpython is stored in a structure like so:

typedef struct {
  PyObject_HEAD
  long ob_ival;
} PyIntObject;

PyObject_HEAD is a macro that expands out into a reference count and a pointer to the type object.

So you can see that:

  • long ob_ival - 4 bytes for a long.
  • Py_ssize_t ob_refcnt - I would assume to size_t here is 4 bytes.
  • PyTypeObject *ob_type - Is a pointer, so another 4 bytes.

12 bytes in total!

Community
  • 1
  • 1
Aesthete
  • 18,622
  • 6
  • 36
  • 45