Расположение Python ints низкой стоимости в памяти

Мой вопрос: где делают эти шаблоны (ниже) происходят?

Я узнал (где-нибудь), что Python имеет уникальные "копии", если это - правильное слово для маленьких целых чисел. Например:

>>> x = y = 0
>>> id(0)
4297074752
>>> id(x)
4297074752
>>> id(y)
4297074752
>>> x += 1
>>> id(x)
4297074728
>>> y
0

Когда я смотрю на ячейки памяти ints, рано существует простой шаблон:

>>> N = id(0)
>>> for i in range(5):
...     print i, N - id(i)
... 
0 0
1 24
2 48
3 72
4 96
>>> bin(24)
'0b11000'

Мне не ясно, почему это выбрано в качестве инкремента. Кроме того, я не могу объяснить этот шаблон вообще выше 256:

>>> prev = 0
>>> for i in range(270):
...     t = (id(i-1), id(i))
...     diff = t[0] - t[1]
...     if diff != prev:
...         print i-1, i, t, diff
...         prev = diff
... 
-1 0 (4297074776, 4297074752) 24
35 36 (4297073912, 4297075864) -1952
36 37 (4297075864, 4297075840) 24
76 77 (4297074904, 4297076856) -1952
77 78 (4297076856, 4297076832) 24
117 118 (4297075896, 4297077848) -1952
118 119 (4297077848, 4297077824) 24
158 159 (4297076888, 4297078840) -1952
159 160 (4297078840, 4297078816) 24
199 200 (4297077880, 4297079832) -1952
200 201 (4297079832, 4297079808) 24
240 241 (4297078872, 4297080824) -1952
241 242 (4297080824, 4297080800) 24
256 257 (4297080464, 4297155264) -74800
257 258 (4297155072, 4297155288) -216
259 260 (4297155072, 4297155336) -264
260 261 (4297155048, 4297155432) -384
261 262 (4297155024, 4297155456) -432
262 263 (4297380280, 4297155384) 224896
263 264 (4297155000, 4297155240) -240
264 265 (4297155072, 4297155216) -144
266 267 (4297155072, 4297155168) -96
267 268 (4297155024, 4297155144) -120

Какие-либо мысли, подсказки, помещают к взгляду?

Править: и что является особенным приблизительно 24?

Обновление: стандартная библиотека имеет sys.getsizeof() который возвращается 24 когда я называю его с 1 как аргумент. Это - много байтов, но на 64-разрядной машине, у нас есть 8 байтов каждый для типа, значения и касательно количества. Кроме того, посмотрите здесь, и ссылка API C здесь.

Проведенный некоторое время с "источником" в ссылке от Peter Hansen в комментариях. Не удалось найти определение интервала (вне объявления *int_int), но я действительно находил:

#define NSMALLPOSINTS       257
#define NSMALLNEGINTS       5

5
задан telliott99 4 February 2010 в 14:14
поделиться

6 ответов

400 изображения на пользователя кажутся высокими? Это цифра из фактической статистики?

Amazon S3 - это здорово, и это просто работает!

Возможным более дешевым вариантом является Google. Теперь документы Google поддерживают все типы файлов, поэтому можно загружать изображения в папку документов Google и совместно использовать эту папку для общего доступа. URL-адреса являются длинными, например,

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I

Добавьте параметр = s для масштабирования изображения, круто! например, для 200 пикселов шириной

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I=s200

Google взимает USD5/year только за 20GB. Существует полный API для загрузки документов и т.д.

-121--3383582-

_ является псевдонимом для функции gettext для перевода.

gettext принимает исходную последовательность в качестве ввода и находит для нее перевод. Этот подход имеет то преимущество, что если перевод не существует, из него будет получена разумная последовательность по умолчанию.

Чтобы отразить это свойство, найденный код по существу создает «всегда сбойную» версию этой функции в случае, если gettext недоступен.

-121--2827328-

Целые числа с низким значением выделяются заранее, целые числа с высоким значением назначаются всякий раз, когда они вычисляются. Целые числа, отображаемые в исходном коде, являются одним и тем же объектом. В моей системе

>>> id(2) == id(1+1)
True
>>> id(1000) == id(1000+0)
False
>>> id(1000) == id(1000)
True

Вы также заметите, что идентификаторы зависят от системы. Это просто адреса памяти, назначенные системным распределителем (или, возможно, компоновщиком, для статических объектов?)

>>> id(0)
8402324

Edit: Причина id (1000) = = id (1000) в том, что компилятор Python замечает, что две целочисленные константы в компилируемом коде одинаковы, поэтому он выделяет только один объект для обоих. Это было бы неприемлемым попаданием производительности во время выполнения, но во время компиляции это не заметно. (Да, интерпретатор также является компилятором. Большинство переводчиков также являются составителями, очень немногие - нет.)

8
ответ дан 18 December 2019 в 11:56
поделиться

Кажется, я припоминаю, что Python внутренне кэширует копии int <256, чтобы избежать необходимости создавать новые объекты Python для часто используемых случаев. Итак, как только вы превысите 256, вы каждый раз будете получать вновь созданные объекты, которые могут казаться «случайными» размещенными в памяти (очевидно, их расположение будет иметь смысл для распределителя Python, но, вероятно, не для нас).

2
ответ дан 18 December 2019 в 11:56
поделиться

Поскольку другие полностью ответили, почему идентификаторы имеют четкий шаблон до 256, я подумал, что отвечу на ваше дополнение: 24 - это размер в байтах целочисленного объекта в python. Когда выделяются первые 256 целых чисел, они размещаются в памяти непрерывно, что приводит к разнице в 24 между каждым адресом памяти.

2
ответ дан 18 December 2019 в 11:56
поделиться

Первые 256 дюймов предварительно распределены

>>> for n in range(1000):
>>>  if id(n) != id(n+0):
>>>   print n
>>>   break

257
2
ответ дан 18 December 2019 в 11:56
поделиться

целые числа до 256 интернированы, поэтому там виден "шаблон". Все остальные целые числа создаются во время выполнения и как таковые выделяются случайным образом id.

1
ответ дан 18 December 2019 в 11:56
поделиться
0
ответ дан 18 December 2019 в 11:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: