2009-03-15 5 views
44

Для некоторого кэширования, который я собираюсь сделать для предстоящего проекта, я думал о сериализации Java. А именно, следует ли его использовать?Высокопроизводительная сериализация: Java vs Google Protocol Buffers vs ...?

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

У кого-нибудь был опыт использования высокопроизводительных GPB? Как он сравнивается с точки зрения скорости и эффективности с собственной сериализацией Java? В качестве альтернативы, есть ли какие-либо другие схемы, которые стоит рассмотреть?

+0

Всестороннее сравнение производительности различных форматов сериализации - http://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/ – Maxim

+0

Я знаю, это старый вопрос, но есть Benchmark-Project https://github.com/eishay/jvm-serializers/wiki, посвященный сериализации Java. – kromit

ответ

55

Я не сравнивал протокольные буферы с собственной сериализацией Java с точки зрения скорости, но для интероперабельности. Собственная сериализация Java является серьезной проблемой no-no. В большинстве случаев это также не так эффективно с точки зрения пространства, как протокольные буферы. Конечно, это несколько более гибко с точки зрения того, что он может хранить, и с точки зрения ссылок и т. Д. Буферы протоколов очень хороши в том, для чего он предназначен, и когда он соответствует вашим потребностям, это здорово - но есть очевидные ограничения из-за совместимости (и другие вещи).

Недавно я опубликовал базовую платформу протоколов буферов в Java и .NET. Версия Java находится в main Google project (в), версия .NET находится в my C# port project. Если вы хотите сравнить скорость PB со скоростью сериализации Java, вы можете написать похожие классы и сравнить их. Если вы заинтересованы в interop, хотя, я бы действительно не дал собственную сериализацию Java (или родную двоичную сериализацию .NET) вторую мысль.

Есть и другие варианты интероперабельной сериализации, кроме протокольных буферов, хотя - Thrift, JSON и YAML Приходят в голову, и есть, несомненно, другие.

EDIT: Хорошо, если interop не так важен, стоит попытаться перечислить различные качества, которые вы хотите, из рамки сериализации. Одна вещь, о которой вы должны подумать, это управление версиями - это еще одна вещь, которую PB предназначен для хорошей обработки, как назад, так и вперед (так что новое программное обеспечение может читать старые данные и наоборот) - когда вы придерживаетесь предложенных правил, конечно :)

Попытавшись быть осторожным в отношении производительности Java и собственной сериализации, я действительно не удивлюсь, что PB все равно будет быстрее. Если у вас есть такая возможность, используйте сервер vm - мои недавние тесты показали, что VM сервера в два раза быстрее при сериализации и десериализации данных образца. Я думаю, что код PB подходит для JIT сервера VM очень хорошо :)

Как примерные показатели производительности, сериализация и десериализация двух сообщений (один 228 байт, один 84750 байт) Я получил эти результаты на своем ноутбуке с использованием VM сервера:

 
Benchmarking benchmarks.GoogleSize$SizeMessage1 with file google_message1.dat 
Serialize to byte string: 2581851 iterations in 30.16s; 18.613789MB/s 
Serialize to byte array: 2583547 iterations in 29.842s; 18.824497MB/s 
Serialize to memory stream: 2210320 iterations in 30.125s; 15.953759MB/s 
Deserialize from byte string: 3356517 iterations in 30.088s; 24.256632MB/s 
Deserialize from byte array: 3356517 iterations in 29.958s; 24.361889MB/s 
Deserialize from memory stream: 2618821 iterations in 29.821s; 19.094952MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage1 with file google_message1.dat 
Serialize to byte string: 17068518 iterations in 29.978s; 123.802124MB/s 
Serialize to byte array: 17520066 iterations in 30.043s; 126.802376MB/s 
Serialize to memory stream: 7736665 iterations in 30.076s; 55.93307MB/s 
Deserialize from byte string: 16123669 iterations in 30.073s; 116.57947MB/s 
Deserialize from byte array: 16082453 iterations in 30.109s; 116.14243MB/s 
Deserialize from memory stream: 7496968 iterations in 30.03s; 54.283176MB/s 

Benchmarking benchmarks.GoogleSize$SizeMessage2 with file google_message2.dat 
Serialize to byte string: 6266 iterations in 30.034s; 16.826494MB/s 
Serialize to byte array: 6246 iterations in 30.027s; 16.776697MB/s 
Serialize to memory stream: 6042 iterations in 29.916s; 16.288969MB/s 
Deserialize from byte string: 4675 iterations in 29.819s; 12.644595MB/s 
Deserialize from byte array: 4694 iterations in 30.093s; 12.580387MB/s 
Deserialize from memory stream: 4544 iterations in 29.579s; 12.389998MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage2 with file google_message2.dat 
Serialize to byte string: 39562 iterations in 30.055s; 106.16416MB/s 
Serialize to byte array: 39715 iterations in 30.178s; 106.14035MB/s 
Serialize to memory stream: 34161 iterations in 30.032s; 91.74085MB/s 
Deserialize from byte string: 36934 iterations in 29.794s; 99.98019MB/s 
Deserialize from byte array: 37191 iterations in 29.915s; 100.26867MB/s 
Deserialize from memory stream: 36237 iterations in 29.846s; 97.92251MB/s 

«Скорость» и «размер» - это то, был ли сгенерированный код оптимизирован для скорости или размера кода. (Сериализованные данные в обоих случаях одинаковы. Версия «размер» предоставляется для случая, когда вы определили много сообщений и не хотите получать много памяти для кода.)

Как вы можете видеть, для меньшего сообщения это может быть очень быстро - более 500 небольших сообщений, сериализованных или десериализованных за миллисекунду. Даже с сообщением 87K он принимает менее миллисекунды за сообщение.

+0

Я должен отметить, что .Net-совместимость не является ключевым требованием. Организация - это 100% Java, но у проекта будет жизнь не менее 5 лет, поэтому я просто думаю о будущем. – cletus

+0

Не могли бы вы предоставить ссылку на базовую платформу? –

+0

Ссылка добавлена ​​в текст - в основном http://code.google.com/p/protobuf/source/browse/#svn/trunk/benchmarks –

5

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

Я не видел много тестов для сериализации/десериализации, но мало поддержки меньше, чем 200 микросекунд для сериализации/десериализации.

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

+0

Вы упоминаете «немного поддержки менее 200 микросекунд». Не могли бы вы сказать, о чем думаете? –

+0

Сериализация Java уже «двоичный формат». Я бы также сказал, что точные измерения в отсутствие знания того, что сериализуется (и компьютер, на котором он работает), довольно бессмысленны. Сериализация/десериализация - это более значимая мера, но она все еще зависит от компьютера. –

+2

См. Мои контрольные показатели для примеров сериализации или десериализации * маленького * сообщения в * * * * * * * * * * * * * * 0 * –

1

Вот от стены предложения дня :-) (вы просто переделаны что-то в моей голове, что я теперь хочу попробовать) ...

Если вы можете пойти на весь раствор кэширования через этот он может работать: Project Darkstar. Он разработан как очень высокопроизводительный игровой сервер, в частности, так что чтение выполняется быстро (так хорошо для кеша). У этого есть Java и C API, поэтому я верю (думал, что прошло много времени с тех пор, как я посмотрел на него, и тогда я не думал об этом), чтобы вы могли сохранять объекты с Java и читать их обратно на C и наоборот.

Если ничего это даст вам то, чтобы читать на сегодня :-)

6

Если вы смешиваете между PB & родной сериализация на скорость и эффективность, просто пойти на ПБ.

  • PB был разработан для достижения таких факторов. См. http://code.google.com/apis/protocolbuffers/docs/overview.html
  • Данные PB очень малы, в то время как сериализация Java имеет тенденцию реплицировать целый объект, включая его подпись. Почему я всегда получаю имя моего класса, название поля ... сериализованное, хотя я знаю его наизнанку в приемнике?
  • Подумайте о развитии языка. Это становится трудно, если одна сторона использует Java, с одной стороны использует C++ ...

Некоторые разработчики предлагают «Стрит», но я бы использовал Google PB, потому что «я верю в Google» :-) .. Во всяком случае, это стоит того взгляд: точка http://stuartsierra.com/2008/07/10/thrift-vs-protocol-buffers

14

еще один данные: этот проект:

http://code.google.com/p/thrift-protobuf-compare/

дает некоторое представление об ожидаемом исполнении для небольших объектов, в том числе Java сериализации на ПБ.

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

5

Вы также можете взглянуть на FST, замену на встроенную сериализацию JDK, которая должна быть более быстрой и иметь меньший выход.

сырые оценки на частые сравнительного анализа я сделал в последние годы:

100% = двоичные/подходы, основанные структура (например,SBE, FST-структура)

  • неудобных
  • постобработки (строить "реальный" obejcts на стороне приемника) может съедают преимущества в производительности и никогда не включаются в тестах

~ 10% -35 % Protobuf & дериватов

~ 10% -30% быстро сериализаторов, такие как FST и Kryo

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

~ 2% -15% JDK сериализации

~ 1% -15% быстрее JSON (например, Джексон)

  • не может обработать любой граф объектов, но только небольшое подмножество структур данных ява
  • нет ссылок не восстанавливающий

0.001-1% полный граф JSON/XML (например, JSON.io)

Эти цифры предназначены для создания очень грубого порядка величины. Обратите внимание, что производительность зависит от LOT в структурах данных, которые сериализуются/сравниваются. Таким образом, простые тесты простого класса в основном бесполезны (но популярны: например, игнорирование unicode, никаких коллекций ...).

смотри также

http://java-is-the-new-c.blogspot.de/2014/12/a-persistent-keyvalue-server-in-40.html

http://java-is-the-new-c.blogspot.de/2013/10/still-using-externalizable-to-get.html

+0

FST отлично поработал с mapdb. –

0

Для проволочного дружеский сериализации, рассмотреть возможность использования Externalizable интерфейса. Используемый умный, у вас будет интимная информация, чтобы решить, как оптимально сортировать и отменять определенные поля. Тем не менее, вам нужно правильно управлять версиями каждого объекта - легко разбить маркер, но перенастраивать объект V2, когда ваш код поддерживает V1, либо сломается, либо потеряет информацию, либо ухудшит поврежденные данные таким образом, что ваши приложения не могут правильно обработать. Если вы ищете оптимальный путь, будьте осторожны, никакая библиотека не решит вашу проблему без каких-либо компромиссов. Как правило, библиотеки подходят для большинства случаев использования и будут иметь дополнительное преимущество, которое они будут адаптировать и улучшать с течением времени без вашего ввода, если вы выбрали активный проект с открытым исходным кодом. И они могут добавить проблемы с производительностью, ввести ошибки и даже исправить ошибки, которые еще не повлияли на вас!

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

  • Нет связанных вопросов^_^