Быстрая сериализация JSON (и сравнение с Рассолом) для кластерных вычислений в Python?

У меня есть ряд точек данных, каждый описанный словарем. Обработка каждой точки данных независима, и я отправляю каждого как отдельное задание к кластеру. Каждая точка данных имеет уникальное имя, и моя кластерная обертка представления просто называет сценарий, который берет имя точки данных и файл, описывающий все точки данных. Тот сценарий затем получает доступ к точке данных из файла и выполняет вычисление.

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

Я пытался использовать JSONpickle, с помощью следующего метода, сериализировать словарь, описывающий все точки данных в файл:

def json_serialize(obj, filename, use_jsonpickle=True):
    f = open(filename, 'w')
    if use_jsonpickle:
    import jsonpickle
    json_obj = jsonpickle.encode(obj)
    f.write(json_obj)
    else:
    simplejson.dump(obj, f, indent=1)   
    f.close()

Словарь содержит очень простые объекты (списки, строки, плавания, и т.д.) и имеет в общей сложности 54 000 ключей. json файл составляет ~20 мегабайтов в размере.

Требуется ~20 секунд для загрузки этого файла в память, которая кажется очень медленной мне. Я переключился на использование рассола с тем же точным объектом и нашел, что это генерирует файл, это составляет приблизительно 7,8 мегабайтов в размере и может быть загружено через ~1-2 секунды. Это - существенное улучшение, но все еще кажется, что загрузка маленького объекта (меньше чем 100 000 записей) должна быть быстрее. Кроме этого, рассол не человекочитаем, который был большим преимуществом JSON для меня.

Существует ли способ использовать JSON для получения подобных или лучших взлетов скорости? В противном случае у Вас есть другие идеи структурировать это?

(Правильное решение состоит в том, чтобы просто "нарезать" файл, описывающий каждое событие в отдельный файл, и передать это на сценарий, который выполняет точку данных в кластерном задании? Это походит, который мог привести к быстрому увеличению файлов).

спасибо.

5
задан Amro 2 July 2012 в 07:28
поделиться

2 ответа

marshal - самый быстрый, но pickle как таковой нет - возможно, вы имеете в виду cPickle (что довольно быстро, особенно с -1 протокол). Итак, помимо проблем с удобочитаемостью, вот код, показывающий различные возможности:

import pickle
import cPickle
import marshal
import json

def maked(N=5400):
  d = {}
  for x in range(N):
    k = 'key%d' % x
    v = [x] * 5
    d[k] = v
  return d
d = maked()

def marsh():
  return marshal.dumps(d)

def pick():
  return pickle.dumps(d)

def pick1():
  return pickle.dumps(d, -1)

def cpick():
  return cPickle.dumps(d)

def cpick1():
  return cPickle.dumps(d, -1)

def jso():
  return json.dumps(d)

def rep():
  return repr(d)

и их скорость на моем ноутбуке:

$ py26 -mtimeit -s'import pik' 'pik.marsh()'
1000 loops, best of 3: 1.56 msec per loop
$ py26 -mtimeit -s'import pik' 'pik.pick()'
10 loops, best of 3: 173 msec per loop
$ py26 -mtimeit -s'import pik' 'pik.pick1()'
10 loops, best of 3: 241 msec per loop
$ py26 -mtimeit -s'import pik' 'pik.cpick()'
10 loops, best of 3: 21.8 msec per loop
$ py26 -mtimeit -s'import pik' 'pik.cpick1()'
100 loops, best of 3: 10 msec per loop
$ py26 -mtimeit -s'import pik' 'pik.jso()'
10 loops, best of 3: 138 msec per loop
$ py26 -mtimeit -s'import pik' 'pik.rep()'
100 loops, best of 3: 13.1 msec per loop

так что читаемость и может быть в десять раз быстрее, чем ] json.dumps с repr (вы жертвуете простотой синтаксического анализа из Javascript и других языков); вы можете получить абсолютную максимальную скорость с marshal , почти в 90 раз быстрее, чем json ; cPickle предлагает гораздо большую универсальность (с точки зрения того, что вы можете сериализовать), чем json или marshal , но если вы никогда не собираетесь использовать эту универсальность, тогда вы также можете использовать marshal (или repr , если удобочитаемость человека важнее скорости).

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

7
ответ дан 14 December 2019 в 04:33
поделиться

Я думаю, здесь вы сталкиваетесь с компромиссом: удобочитаемость достигается за счет производительности и большого размера файла. Таким образом, из всех методов сериализации, доступных в Python, JSON не только самый читаемый, но и самый медленный.

Если бы мне нужно было стремиться к производительности (и компактности файлов), я бы выбрал marshall . Вы можете либо упорядочить весь набор с помощью dump () и load () , либо, основываясь на своей идее разделения вещей, упорядочить отдельные части набора данных в отдельные файлы. Таким образом вы откроете дверь для распараллеливания обработки данных - если вам так хочется.

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

1
ответ дан 14 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

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