Comments 19
Redis
+1
Не то…
Покажите аналог кода, приведенного в посте, для Redis.
Готов поспорить, получится сильно уродливей…
Покажите аналог кода, приведенного в посте, для Redis.
Готов поспорить, получится сильно уродливей…
0
Упс, не весь комментарий отправился
Я хотел сказать что Redis в бекенды было бы неплохо добавить.
Я хотел сказать что Redis в бекенды было бы неплохо добавить.
+6
github.com/iamteem/redisco — аналогичная штука для Redis, было бы интересно сравнить производительность с odbm, особенно более сложных выборок, а не просто get/set
0
В pymorphy тоже делал похожие обертки над tc, cdb, bsddb и sqlite. Я тогда там не стал выдумывать свой api, а унаследовался от DbfilenameShelf из стандартной библиотеки (решение и решение). Плюс запись была почти не нужна, интересовало главным образом чтение.
Выводы:
1. marshal быстрый, но не переносимый. JSON (с каким-нибудь C-расширением вроде simplejson) примерно такой же быстрый (точных цифр не помню, то-ли быстрее, то-ли медленнее немного), но его можно читать где угодно, и формат стабильный. Произвольные питоньи объекты он, впрочем, дампить не умеет. Может, это и хорошо.
2. Из «тупых» key-value хранилищ самое быстрое — cdb (и памяти ест немного меньше tc). Меньше всего оперативной памяти ест bsddb (причем значительно меньше).
3. Sqlite нужен. Он медленнее в несколько раз своих аналогов, но там дико стабильный формат хранения данных, и sqlite-базу можно просто скопировать и перенести куда угодно, все будет работать. Sqlite есть, к тому же, в стандартной библиотеке (начиная с 2.5), так что для использования не нужно ничего ставить и компилировать. Идеальный вариант, когда нужна переносимость и легкость установки. Только не забыть, что там есть проблемы с многопоточностью.
Выводы:
1. marshal быстрый, но не переносимый. JSON (с каким-нибудь C-расширением вроде simplejson) примерно такой же быстрый (точных цифр не помню, то-ли быстрее, то-ли медленнее немного), но его можно читать где угодно, и формат стабильный. Произвольные питоньи объекты он, впрочем, дампить не умеет. Может, это и хорошо.
2. Из «тупых» key-value хранилищ самое быстрое — cdb (и памяти ест немного меньше tc). Меньше всего оперативной памяти ест bsddb (причем значительно меньше).
3. Sqlite нужен. Он медленнее в несколько раз своих аналогов, но там дико стабильный формат хранения данных, и sqlite-базу можно просто скопировать и перенести куда угодно, все будет работать. Sqlite есть, к тому же, в стандартной библиотеке (начиная с 2.5), так что для использования не нужно ничего ставить и компилировать. Идеальный вариант, когда нужна переносимость и легкость установки. Только не забыть, что там есть проблемы с многопоточностью.
0
1. Json сильно медленнее marshal, не уверен что имеет смысл привязываться к переносимости вообще. Привязываться к переносимости при хранении данных. Хранить нужно в том, что быстрее (marshal), а нужно перенести — дампим в переносимый формат. А так мы скоро придём к идее, что разные версии бд не совместимы и начнём как-то её обходить.
2. Вроже ж, cdb не перезаписываемая? Записал раз, а потом только читать или целиком переписывать бд. Или что-то изменилось?
3. Sqlite не понял зачем? Опять же, п.1. Какой смысл пользоваться key-value хранилищем, если оно будет медленным? Переносимость нужна? Тогда вон fsdbm, она pure-python :)
2. Вроже ж, cdb не перезаписываемая? Записал раз, а потом только читать или целиком переписывать бд. Или что-то изменилось?
3. Sqlite не понял зачем? Опять же, п.1. Какой смысл пользоваться key-value хранилищем, если оно будет медленным? Переносимость нужна? Тогда вон fsdbm, она pure-python :)
0
json сильно медленнее marshal без С-расширений, с ними у меня в тестах не медленнее было.
cdb — хм, да, точно. Мне-то запись не нужна была, внимания поэтому на это не обратил)
Sqlite — затем, чтобы можно было попробовать api и решить, нужно ли это все, без всяких хлопот. Sqlite не медленный.
А зачем пользоваться обертками над key/value, если они будут медленными? А простые обертки будет медленными на всем, кроме получения по ключу и записи по ключу. Я ведь правильно понимаю, что User.find(filter=lambda ...) выбирает все записи и фильтрует их на питоне, что использовать этот API на реальных данных смысла будет мало, и тот же sqlite с индексом «уделает» любой такой запрос? Альтернатива — строить свои индексы в k/v хранилищах. Тогда нужна их поддержка в обертке какая-то. Или авто-использование каких-то средств БД (индексы в sqlite, поиск по префиксу в tree db у токио, последовательный перебор в деревьях). Не представляю, как можно реализовать все это, сохранив API с лямбдой. Хотя в монго вроде умеют индекс строить при первом запросе, не разбирался детально. Тут можно извернуться, в принципе: исходный код лямбды через интроспекцию получить, где-то список индексов хранить и обновлять их при сохранении, при совпадении фильтров делать выборку по индексу. Жесь какая-то) Или что-то такое: github.com/dcramer/django-indexer
Разные БД имеют разные возможности. И если цель — скорость, то, скорее всего, все равно же придется использовать хитрые возможности конкретной БД. А если уж завязываться на конкретную БД, то можно и драйвер использовать без обертки, у них обычно api почти такой же простой.
Т.е. теперь не понял, зачем все это: думал, все это для удобства делается, для простоты, для экспериментов, а не для скорости. Если для скорости, то, думаю, может иметь смысл выкинуть метод find: упростится код и не будет соблазна этот метод вызывать.
cdb — хм, да, точно. Мне-то запись не нужна была, внимания поэтому на это не обратил)
Sqlite — затем, чтобы можно было попробовать api и решить, нужно ли это все, без всяких хлопот. Sqlite не медленный.
Какой смысл пользоваться key-value хранилищем, если оно будет медленным?
А зачем пользоваться обертками над key/value, если они будут медленными? А простые обертки будет медленными на всем, кроме получения по ключу и записи по ключу. Я ведь правильно понимаю, что User.find(filter=lambda ...) выбирает все записи и фильтрует их на питоне, что использовать этот API на реальных данных смысла будет мало, и тот же sqlite с индексом «уделает» любой такой запрос? Альтернатива — строить свои индексы в k/v хранилищах. Тогда нужна их поддержка в обертке какая-то. Или авто-использование каких-то средств БД (индексы в sqlite, поиск по префиксу в tree db у токио, последовательный перебор в деревьях). Не представляю, как можно реализовать все это, сохранив API с лямбдой. Хотя в монго вроде умеют индекс строить при первом запросе, не разбирался детально. Тут можно извернуться, в принципе: исходный код лямбды через интроспекцию получить, где-то список индексов хранить и обновлять их при сохранении, при совпадении фильтров делать выборку по индексу. Жесь какая-то) Или что-то такое: github.com/dcramer/django-indexer
Разные БД имеют разные возможности. И если цель — скорость, то, скорее всего, все равно же придется использовать хитрые возможности конкретной БД. А если уж завязываться на конкретную БД, то можно и драйвер использовать без обертки, у них обычно api почти такой же простой.
Т.е. теперь не понял, зачем все это: думал, все это для удобства делается, для простоты, для экспериментов, а не для скорости. Если для скорости, то, думаю, может иметь смысл выкинуть метод find: упростится код и не будет соблазна этот метод вызывать.
0
import cPickle as pickle
import simplejson as json
import marshal
from time import time
data = range(100)
for dumper in [json, pickle, marshal]:
start = time()
for i in xrange(1000):
dumper.dumps(data)
print dumper.__name__, time() - start
simplejson 0.0725080966949
cPickle 0.0695569515228
marshal 0.00670003890991
+2
Смотрите, у меня на более сложных объектах сериализации cPickle показал наихудший результат.
Ваш вариант:
simplejson 0.0211260318756
cPickle 0.0203590393066
marshal 0.00218415260315
data = [{'var1': 100, 'other_variable': 'empty text', 'index': i} for i in range(100)]
simplejson 0.129426956177
cPickle 0.256888866425
marshal 0.0233998298645
Интересно что marshal вообще практически не замедлился.
Ваш вариант:
simplejson 0.0211260318756
cPickle 0.0203590393066
marshal 0.00218415260315
data = [{'var1': 100, 'other_variable': 'empty text', 'index': i} for i in range(100)]
simplejson 0.129426956177
cPickle 0.256888866425
marshal 0.0233998298645
Интересно что marshal вообще практически не замедлился.
0
По sqlite понял, добавлю.
> А зачем пользоваться обертками над key/value, если они будут медленными? А простые обертки будет медленными на всем, кроме получения по ключу и записи по ключу.
Ну, вот в случаях, когда этого достаточно и пользоваться. И на практике таких случаев большая часть. Как только мышление настроится, чтобы их замечать :)
Лямбды — да. Они по большей части для администрирования бд, не для пользовательских запросов.
> А зачем пользоваться обертками над key/value, если они будут медленными? А простые обертки будет медленными на всем, кроме получения по ключу и записи по ключу.
Ну, вот в случаях, когда этого достаточно и пользоваться. И на практике таких случаев большая часть. Как только мышление настроится, чтобы их замечать :)
Лямбды — да. Они по большей части для администрирования бд, не для пользовательских запросов.
0
>Т.е. теперь не понял, зачем все это: думал, все это для удобства делается, для простоты, для экспериментов, а не для скорости. Если для скорости, то, думаю, может иметь смысл выкинуть метод find: упростится код и не будет соблазна этот метод вызывать.
Для скорости. А find() для эксперементов :) Хотя на табличках <= 1к записей, уверен, он порвёт sqlite с индексами. А если условие выборки будет посложнее, то и на больших табличках. В лямбдах можно очень хитрое условие обработать, а попробуй переложить это на sql, очень жёстко получится.
Для скорости. А find() для эксперементов :) Хотя на табличках <= 1к записей, уверен, он порвёт sqlite с индексами. А если условие выборки будет посложнее, то и на больших табличках. В лямбдах можно очень хитрое условие обработать, а попробуй переложить это на sql, очень жёстко получится.
0
Трансляцию лямбды в SQL успешно делает GeniuSQL, но это единичный случай, тк странно и сложно.
0
А теперь осталось найти готовые решения для обеспечения многопроцессорного доступа к данным с передачей процессам событий изменения…
Задачи вида — 2,3,… процесса работают с объемной общей базой и нужны быстрые средства синхронизации изменений данных между ними, хотя бы с рабочим пулом/кешем, в идеале без лага.
Вариант с перечитыванием в цикле данных в ожидании изменений точно не катит, с чем сейчас работаю — собственная обертка над методами работы с БД, но пока это key-value база — все хорошо, но чуть больше захотеть и начинаются сложности.
Задачи вида — 2,3,… процесса работают с объемной общей базой и нужны быстрые средства синхронизации изменений данных между ними, хотя бы с рабочим пулом/кешем, в идеале без лага.
Вариант с перечитыванием в цикле данных в ожидании изменений точно не катит, с чем сейчас работаю — собственная обертка над методами работы с БД, но пока это key-value база — все хорошо, но чуть больше захотеть и начинаются сложности.
0
Sign up to leave a comment.
odbm = объектная обёртка для key-value хранилищ