2010-04-19 1 views
5

У меня есть набор точек данных, каждый из которых описывается словарем. Обработка каждой точки данных является независимой, и я отправляю каждый в отдельное задание кластеру. Каждая точка данных имеет уникальное имя, а оболочка представления кластера просто вызывает сценарий, который принимает имя точки данных и файл, описывающий все точки данных. Затем этот скрипт обращается к точке данных из файла и выполняет вычисление.Быстрая сериализация JSON (и сравнение с Pickle) для кластерных вычислений в 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 секунд, что кажется очень медленным для меня. Я переключился на использование pickle с тем же самым точным объектом и обнаружил, что он генерирует файл размером около 7,8 мегабайта и может быть загружен через ~ 1-2 секунды. Это значительное улучшение, но по-прежнему кажется, что загрузка небольшого объекта (менее 100 000 записей) должна быть быстрее. Помимо этого, рассол не читается человеком, что явилось большим преимуществом JSON для меня.

Есть ли способ использовать JSON для получения аналогичных или лучших ускорений? Если нет, есть ли у вас другие идеи по структурированию этого?

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

спасибо.

ответ

7

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, если скорость чтения человеком будет лучше).

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

+0

Большое спасибо за ваш информативный ответ, это было очень полезно. Какие базы данных вы бы рекомендовали в python? Я бы очень предпочел вещи, которые не требуют автономных серверов баз данных, или даже лучше, которые встроены в python, возможно, как sqlite - над теми, которые это делают. Любые мысли по этому поводу? Будет ли подход базы данных в Python соперничать с временем рассола для тестового примера словаря для ~ 50 000 ключей, где вам нужно нарезать определенную запись? Если я переключусь на БД, я напишу специальный код для сериализации в CSV, чтобы мои файлы могли быть доступны и прочитаны другими пользователями. – user248237dfsf

+0

Если вы используете встроенную базу данных, тогда SQLite лучше, но, как и любая другая встроенная БД, она не купит вам никакой параллельной обработки, в этом случае большая производительность DB-подхода. Насколько сложно запускать процесс PostgreSQL? И СЕЙЧАС вы получаете идеальное распараллеливание доступа к данным и большую производительность. (Написание CSV или других форм в SQL DB и сброс содержимого базы данных обратно в любую вашу форму, это простая работа с простыми вспомогательными скриптами, конечно же - это независимый от того, какой механизм БД вы выберете). –

1

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

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

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

+0

JSON медленнее, чем XML? Это не кажется правильным ... –

Смежные вопросы