Сериализация списка Python – самый быстрый метод

Мне нужно загрузить (де-сериализовать) предварительно вычисленный список целых чисел из файла в скрипте Python (в список Python). Список большой (до миллионов элементов), и я могу выбрать формат, в котором я его храню, до тех пор, пока загрузка будет самой быстрой.

Какой самый быстрый метод и почему?

  1. Использование import в .py-файле, который просто содержит список, назначенный переменной
  2. Использование cPickle
  3. Какой-то другой метод (возможно, numpy ?)

Кроме того, как можно надежно оценить такие вещи?

Дополнение: измерение этого достоверно затруднено, поскольку import кэшируется, поэтому его нельзя выполнять несколько раз в тесте. Погрузка с рассолом также ускоряется после первого раза, вероятно, из-за того, что ОС выполняет предварительную сборку. Загрузка 1 миллиона номеров с помощью cPickle занимает 1,1 с при первом запуске и 0,2 секунды при последующих cPickle сценария.

Интуитивно я чувствую, что cPickle должен быть быстрее, но я бы оценил цифры (это, по-моему, довольно сложно измерить).

И да, для меня важно, чтобы это выполнялось быстро.

благодаря

6 Solutions collect form web for “Сериализация списка Python – самый быстрый метод”

Я бы предположил, что cPickle будет быстрее, если вам действительно нужна вещь в списке.

Если вы можете использовать массив , который является встроенным типом последовательности, я рассчитал это на четверть секунды для 1 миллиона целых чисел:

 from array import array from datetime import datetime def WriteInts(theArray,filename): f = file(filename,"wb") theArray.tofile(f) f.close() def ReadInts(filename): d = datetime.utcnow() theArray = array('i') f = file(filename,"rb") try: theArray.fromfile(f,1000000000) except EOFError: pass print "Read %d ints in %s" % (len(theArray),datetime.utcnow() - d) return theArray if __name__ == "__main__": a = array('i') a.extend(range(0,1000000)) filename = "a_million_ints.dat" WriteInts(a,filename) r = ReadInts(filename) print "The 5th element is %d" % (r[4]) 

Для бенчмаркинга см. Модуль timeit в стандартной библиотеке Python. Чтобы узнать, что является самым быстрым способом, реализуйте все способы, с помощью которых вы можете думать и измерять их с помощью timeit.

Случайное мышление: в зависимости от того, что вы делаете в точности, вы можете быстрее найти «наборы целых чисел» в стиле, используемом в файлах .newsrc :

 1, 3-1024, 11000-1200000 

Если вам нужно проверить, находится ли что-то в этом наборе, загрузка и сопоставление с таким представлением должны быть одним из самых быстрых способов. Это предполагает, что ваши наборы целых чисел достаточно плотные, с длинными последовательными последовательностями смежных значений.

Чтобы помочь вам в синхронизации, библиотека Python предоставляет модуль timeit :

Этот модуль обеспечивает простой способ ввода небольших битов кода Python. Он имеет как командную строку, так и вызываемые интерфейсы. Он позволяет избежать ряда общих ловушек для измерения времени выполнения.

Пример (из руководства), который сравнивает стоимость использования hasattr() vs. try/except проверки отсутствующих и существующих атрибутов объекта:

 % timeit.py 'try:' ' str.__nonzero__' 'except AttributeError:' ' pass' 100000 loops, best of 3: 15.7 usec per loop % timeit.py 'if hasattr(str, "__nonzero__"): pass' 100000 loops, best of 3: 4.26 usec per loop % timeit.py 'try:' ' int.__nonzero__' 'except AttributeError:' ' pass' 1000000 loops, best of 3: 1.43 usec per loop % timeit.py 'if hasattr(int, "__nonzero__"): pass' 100000 loops, best of 3: 2.23 usec per loop 

«Как можно надежно оценить такие вещи?»

Я не понимаю.

Вы пишете кучу небольших функций для создания и сохранения списка в различных формах.

Вы пишете кучу небольших функций для загрузки своих списков в разных формах.

Вы пишете небольшую функцию таймера, чтобы получить время начала, выполните процедуру загрузки несколько десятков раз (чтобы получить среднее среднее значение, достаточное для того, чтобы шум планирования ОС не доминировал над вашими измерениями).

Вы суммируете свои данные в небольшом отчете.

Что ненадежно?

Вот некоторые несвязанные вопросы, которые показывают, как измерять и сравнивать производительность.

Преобразовать список ints на один номер?

Конкатенация строк и замена строк в Python

Вам нужно всегда загружать весь файл? Если нет, то upak_from () может быть лучшим решением. Предположим, что у вас есть 1000000 целых чисел, но вы хотите загрузить только те из 50000 до 50099, вы бы сделали:

 import struct intSize = struct.calcsize('i') #this value would be constant for a given arch intFile = open('/your/file.of.integers') intTuple5K100 = struct.unpack_from('i'*100,intFile,50000*intSize) 

cPickle будет самым быстрым, так как он сохраняется в двоичном формате, и никакой реальный код python не нужно разбирать.

Другим преимуществом является то, что он более безопасен (поскольку он не выполняет команды), и у вас нет проблем с правильной настройкой $PYTHONPATH .

  • Как десериализовать 1GB объектов в Python быстрее, чем cPickle?
  • Лучший способ сохранения данных
  • Почему загрузка пика и отвала питона раздувают размер объекта на диске?
  • Python: сравнение производительности с использованием `pickle` или` marshal` и использование `re`
  • Шаблоны для преобразования объектов Python (кодирование, декодирование, десериализация, сериализация)
  • Python - лучший язык программирования в мире.