#python #python-3.x #memory
#python #python-3.x #память
Вопрос:
Я знаю, что Python — не лучший язык управления памятью, но есть ли способ хранить небольшие числа в меньшую часть памяти, чем целое число?
В настоящее время я работаю над программой на Python с поиском по ширине и использую один параметр в классе, который может иметь значение только от 0 до 9. Я хочу сохранить это как можно более эффективно, потому что — хорошо, если у меня размер 1B или 3B имеет значение, когда вам нужно просмотреть несколько тысяч переменных в оперативной памяти.
Комментарии:
1. При нескольких тысячах объектов вы все равно будете находиться в диапазоне КБ. Если вы не работаете на какой-то платформе с очень ограниченными ресурсами, это не будет иметь большого значения
2. Это встроенная система? В большинстве случаев обычное целое число достаточно мало, чтобы о нем не беспокоиться.
3. В CPython кэшируются небольшие целые числа. Итак, есть только служебные данные указателя, 8 байт. Однако, если вы хотите сохранить много маленьких целых чисел, вы можете использовать
array.array
или дажеnumpy
Ответ №1:
не уверен, что это действительно того стоит, но вы всегда можете закодировать целые числа в [0, 1, ..., 9]
4 бита и сохранить несколько из них в python int
. их упаковка и распаковка — это затем некоторый сдвиг и маскировка:
SHIFT = 4
MASK = 0xf
integers = [0, 1, 5, 3]
# pack list into int
store = 0
for i in integers:
store <<= SHIFT
store ^= i
# unpack list from int
unpacked = []
for _ in range(len(integers)):
unpacked.append(store amp; MASK)
store >>= SHIFT
unpacked.reverse()
assert integers == unpacked
struct
модуль также может быть полезен.
Ответ №2:
С собственным кодом python вы не можете, поскольку python int
жестко запрограммирован на 24 байта для поддержки длинного целого числа. Что эффективно, поскольку в вашем случае параметр функции принимает однозначное число
Но если вы помните, что C имеет решение, unsigned char
в C занимает 1 байт и имеет диапазон чисел от 0 - 255
Итак, в python это будет выглядеть так
>>> from ctypes import c_ubyte
>>> ten = c_ubyte(10)
>>> ten
c_ubyte(10)
>>> type(ten)
<class 'ctypes.c_ubyte'>
>>> ten.value
10
>>> type(ten.value)
<class 'int'>
>>>
Комментарии:
1. У
ctypes
оболочек нет накладных расходов на память?2. В моей системе это
ctypes.c_ubyte
значение имеет гораздо больше накладных расходов, чем простоеint
. Это было бы полезно только для экономии памяти, если бы вы использовали довольно большой массив ubytes, так что для всех значений существует только один экземпляр накладных расходов.