Moshi vs Gson en Android [cerrado]

81

Estoy decidiendo si usar Moshi por cuadrado o Gson para serializar y deserializar los datos del modelo.

Una cosa que siempre no me gustó de Gson es que creo que usa la reflexión, que puede ser lenta en Android. ¿Moshi también usa la reflexión?

¿Cuáles son algunos de los pros y contras de moshi vs Gson?

Los veo similares. Tomemos, por ejemplo, esta declaración que crea unatypeAdapter:

class CardAdapter {
  @ToJson String toJson(Card card) {
    return card.rank + card.suit.name().substring(0, 1);
  }

  @FromJson Card fromJson(String card) {
    if (card.length() != 2) throw new JsonDataException("Unknown card: " + card);

    char rank = card.charAt(0);
    switch (card.charAt(1)) {
      case 'C': return new Card(rank, Suit.CLUBS);
      case 'D': return new Card(rank, Suit.DIAMONDS);
      case 'H': return new Card(rank, Suit.HEARTS);
      case 'S': return new Card(rank, Suit.SPADES);
      default: throw new JsonDataException("unknown suit: " + card);
    }
  }
}

y para usarlo, regístrelo como en gson:

Moshi moshi = new Moshi.Builder()
.add(new CardAdapter())
.build();

Supongo que las ventajas serían la anotación que se usa en typeAdapter. Estoy buscando averiguar si hay alguna mejora en el rendimiento si cambio a Moshi.

j2emanue
fuente

Respuestas:

94

Moshi usa Okio para optimizar algunas cosas que Gson no hace.

  • Al leer los nombres de los campos , Moshi no tiene que asignar cadenas ni realizar búsquedas de hash.
  • Moshi escanea la entrada como una secuencia de bytes UTF-8, convirtiéndola a caracteres Java de forma perezosa. Por ejemplo, nunca necesita convertir literales enteros en caracteres.

Los beneficios de estas optimizaciones son particularmente pronunciados si ya está utilizando transmisiones de Okio. Los usuarios de Retrofit y OkHttp en particular se benefician de Moshi.

Más información sobre los orígenes de Moshi se encuentra en mi publicación, Moshi, otro procesador JSON .

Jesse Wilson
fuente
¿Usa la reflexión
J2emanue
2
@ j2emanue Como detalle de implementación, los JsonAdapters predeterminados para sus clases personalizadas establecerán campos con reflejo.
Eric Cochran
1
@ j2emanue La reflexión se puede evitar usando codegen github.com/square/moshi#codegen
Pedro Lopes
34

Según el comentario de swankjesse en reddit :

Estoy orgulloso de mi trabajo en Gson, pero también decepcionado por algunas de sus limitaciones. Quería abordarlos, pero no como "Gson 3.0", en parte porque ya no trabajo en Google. Jake, Scott, Eric y yo creamos Moshi para abordar las diversas limitaciones de Gson. Aquí hay diez pequeñas razones para preferir Moshi a Gson:

  1. Próximo apoyo de Kotlin.

  2. Los calificadores como @HexColor int permiten múltiples representaciones JSON para un solo tipo de Java.

  3. @ToJson y @FromJson facilitan la escritura y prueba de adaptadores JSON personalizados.

  4. JsonAdapter.failOnUnknown () le permite rechazar datos JSON inesperados.

  5. Excepciones predecibles. Moshi lanza IOException en problemas de IO y JsonDataException en discrepancias de tipos. Gson está por todos lados.

  6. JsonReader.selectName () evita la decodificación UTF-8 innecesaria y las asignaciones de cadenas en el caso común.

  7. Enviará un APK más pequeño. Gson es 227 KiB, Moshi + Okio juntos son 200 KiB.

  8. Moshi no filtrará los detalles de implementación de los tipos de plataforma en su JSON codificado. Esto me hace temer a Gson: gson.toJson (SimpleTimeZone.getTimeZone ("GMT"))

  9. Moshi no hace escapes HTML extraños por defecto. Mire la codificación predeterminada de Gson de "12 & 5 = 4" como ejemplo.

  10. Ningún adaptador de fecha roto instalado por defecto.

Si está escribiendo código nuevo, le recomiendo comenzar con Moshi. Si tiene un proyecto existente con Gson, debería actualizarlo si es simple y no arriesgado. De lo contrario, ¡quédate con Gson! Estoy haciendo todo lo posible para asegurarme de que siga siendo compatible y confiable.

Ahamadullah Saikat
fuente
1

En el enlace anterior, puede ver que el uso de moshi codegen creará adaptadores de tiempo de compilación para clases de modelo, lo que eliminará el uso de reflexión en tiempo de ejecución

Modelo

@JsonClass(generateAdapter = true) 
class MyModel(val blah: Blah, val blah2: Blah)

app / build.gradle

kapt "com.squareup.moshi:moshi-kotlin-codegen:$version_moshi"

Generará una clase MyModelJsonAdapter con validaciones para garantizar la nulidad de las propiedades del modelo.

Germán
fuente
¿No pensarías que moshi es más rápido entonces?
j2emanue