88 votes

Moshi vs Gson dans Android

Je suis en train de décider si je dois utiliser Moshi en carré ou Gson pour sérialiser et désérialiser les données du modèle.

Une chose que je n'ai jamais aimé à propos de Gson est qu'il utilise la réflexion, ce qui peut être lent sur Android ? Moshi utilise-t-il aussi la réflexion ?

Quels sont les avantages et les inconvénients de Moshi par rapport à Gson ?

Je les vois comme similaires. Prenez par exemple cette déclaration qui crée une typeAdapter:

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);
    }
  }
}

et pour l'utiliser, enregistrez-le comme dans gson :

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

Je suppose que l'avantage serait que l'annotation soit utilisée dans le typeAdapter. Je cherche à savoir s'il y a des gains de performance si je passe à Moshi.

104voto

Jesse Wilson Points 8455

Moshi utilise Okio pour optimiser certaines choses que Gson ne fait pas.

  • En lecture des noms de champs Moshi n'a pas besoin d'allouer des chaînes de caractères ou de faire des recherches de hachage.
  • Moshi analyse l'entrée comme une séquence d'octets UTF-8, et la convertit en caractères Java paresseusement. Par exemple, il n'a jamais besoin de convertir les littéraux entiers en caractères.

Les avantages de ces optimisations sont particulièrement prononcés si vous utilisez déjà les flux Okio. Les utilisateurs de Rétrofit y OkHttp bénéficient en particulier de Moshi.

De plus amples discussions sur les origines de Moshi sont dans mon post, Moshi, un autre processeur JSON .

0 votes

Utilise-t-il la réflexion

2 votes

@j2emanue En tant que détail d'implémentation, les JsonAdapters par défaut pour vos classes personnalisées définiront les champs avec réflexion.

1 votes

@j2emanue Reflection peut être évité en utilisant codegen github.com/square/moshi#codegen

47voto

Selon commentaire de swankjesse sur reddit :

Je suis fier de mon travail sur Gson, mais aussi déçu par certaines de ses limites. Je voulais y remédier, mais pas en tant que "Gson 3.0", en partie parce que je ne travaille plus chez Google. Jake, Scott, Eric et moi-même avons créé Moshi pour répondre aux diverses limitations de Gson. Voici dix petites raisons de préférer Moshi à Gson :

  1. Support Kotlin à venir.

  2. Les qualificatifs tels que @HexColor int autorisent plusieurs représentations JSON pour un seul type Java.

  3. Les fonctions @ToJson et @FromJson facilitent l'écriture et le test d'adaptateurs JSON personnalisés.

  4. JsonAdapter.failOnUnknown() vous permet de rejeter les données JSON inattendues.

  5. Des exceptions prévisibles. Moshi lance des IOException sur les problèmes d'E/S et des JsonDataException sur les incompatibilités de type. Gson est un peu partout.

  6. JsonReader.selectName() évite le décodage UTF-8 inutile et les allocations de chaînes dans le cas courant.

  7. Vous enverrez un APK plus petit. Gson fait 227 KiB, Moshi+Okio ensemble font 200 KiB.

  8. Moshi ne divulguera pas les détails d'implémentation des types de plateformes dans votre JSON encodé. Cela me fait craindre Gson : gson.toJson(SimpleTimeZone.getTimeZone("GMT"))

  9. Moshi ne fait pas d'échappement HTML bizarre par défaut. Regardez l'encodage par défaut de Gson "12 & 5 = 4" pour un exemple.

  10. Aucun adaptateur de date cassée installé par défaut.

Si vous écrivez du nouveau code, je vous recommande vivement de commencer avec Moshi. Si vous avez un projet existant avec Gson, vous devriez le mettre à jour si cela est simple et sans risque. Sinon, restez avec Gson ! Je fais de mon mieux pour m'assurer qu'il reste compatible et fiable.

1voto

Herman Points 456

À partir du lien précédent, vous pouvez voir que l'utilisation de moshi codegen créera des adaptateurs au moment de la compilation pour les classes de modèles, ce qui supprimera l'utilisation de la réflexion au moment de l'exécution.

Modèle

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

app/build.gradle

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

Génère une classe MyModelJsonAdapter avec des validations pour assurer la nullité des propriétés du modèle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X