Подтвердить что ты не робот

Простая, беспроблемная, нулевая схематизация сериализации в Scala/Java, похожая на Python Pickle?

Есть ли простой, беспроблемный подход к сериализации в Scala/Java, который похож на Python pickle? Pickle - это мертвое простое решение, которое разумно эффективно в пространстве и времени (то есть не является абсурдным), но не заботится о возможности межязыкового доступа, управления версиями и т.д. И допускает дополнительную настройку.

Что я знаю:

Kryo и protostuff - самые близкие решения, которые я нашел, но мне интересно, есть ли там что-нибудь еще (или если есть способ использовать их, о которых я должен знать). Пожалуйста, включите примеры использования! В идеале также включают контрольные показатели.

4b9b3361

Ответ 1

Scala теперь имеет Scala -pickling, который работает как хорошо или лучше, чем Kyro, в зависимости от сценария - см. слайды 34-39 в этой.

Ответ 2

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

Рассол Python

import pickle
import time
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
people = [Person("Alex", 20), Person("Barbara", 25), Person("Charles", 30), Person("David", 35), Person("Emily", 40)]
for i in xrange(10000):
    output = pickle.dumps(people, -1)
    if i == 0: print len(output)
start_time = time.time()
for i in xrange(10000):
    output = pickle.dumps(people, -1)
print time.time() - start_time    

Вывод 174 байта и 1,18-1,23 секунды для меня (Python 2.7.1 на 64-разрядной Linux)

Scala kryo

import com.esotericsoftware.kryo._
import java.io._
class Person(val name: String, val age: Int)
object MyApp extends App {
  val people = Array(new Person("Alex", 20), new Person("Barbara", 25), new Person("Charles", 30), new Person("David", 35), new Person("Emily", 40))
  val kryo = new Kryo
  kryo.setRegistrationOptional(true)
  val buffer = new ObjectBuffer(kryo)
  for (i <- 0 until 10000) {
    val output = new ByteArrayOutputStream
    buffer.writeObject(output, people)
    if (i == 0) println(output.size)
  }
  val startTime = System.nanoTime
  for (i <- 0 until 10000) {
    val output = new ByteArrayOutputStream
    buffer.writeObject(output, people)
  }
  println((System.nanoTime - startTime) / 1e9)
}

Вывод 68 байтов для меня и 30-40 мс (Kryo 1.04, Scala 2.9.1, Java 1.6.0.26 hotspot JVM на 64-разрядной Linux). Для сравнения, он выдает 51 байт и 18-25 мс, если я зарегистрирую классы.

Сравнение

Kryo использует около 40% пространства и 3% времени, когда Python раскроет, когда не регистрирует классы, и около 30% пространства и 2% времени при регистрации классов. И вы всегда можете написать собственный сериализатор, если хотите больше контроля.

Ответ 3

Twitter chill library просто потрясающе. Он использует Kryo для сериализации, но очень прост в использовании. Также приятно: предоставляет тип MeatLocker [X], который делает любой X сериализуемым.

Ответ 4

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

Пример использования для простого ADT

Ответ 5

Еще один хороший вариант - недавний (2016) **netvl/picopickle**:

  • Маленький и почти без зависимостей (основная библиотека зависит только от shapeless).
  • Расширяемость. Вы можете определить свои собственные сериализаторы для своих типов, и вы можете создавать собственные бэкэнды, то есть вы можете использовать одну и ту же библиотеку для разных форматов сериализации (коллекции, JSON, BSON и т.д..); другие части поведения сериализации, такие как обработка нулей, также могут быть настроены.
  • Гибкость и удобство: формат сериализации по умолчанию подходит для большинства целей, но может быть настроен практически произвольно с поддержкой из удобных конвертеров DSL.
  • Статическая сериализация без отражения: бесформенный Общие макросы используются для предоставления сериализаторов для произвольных типов, что означает отсутствие отражения.

Например:

Ящик, основанный на ястрефе, также предоставляет дополнительные функции readString()/writeString() и readAst()/writeAst(), которые [де] сериализуют объекты для строк и JSON AST для строк соответственно:

import io.github.netvl.picopickle.backends.jawn.JsonPickler._

case class A(x: Int, y: String)

writeString(A(10, "hi")) shouldEqual """{"x":10,"y":"hi"}"""
readString[A]("""{"x":10,"y":"hi"}""") shouldEqual A(10, "hi")