Moshi vs Gson in Android [geschlossen]

81

Ich entscheide mich, ob ich Moshi by Square oder Gson zum Serialisieren und Deserialisieren von Modelldaten verwenden soll.

Eine Sache, die ich an Gson immer nicht mochte, ist, dass ich denke, dass es Reflexionen verwendet, die auf Android langsam sein können. Verwendet Moshi auch Reflexion?

Was sind einige der Vor- und Nachteile von Moshi gegen Gson?

Ich sehe sie als ähnlich. Nehmen Sie zum Beispiel diese Anweisung, die eine erstellttypeAdapter:

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

und um es zu benutzen, registriere es genau wie in gson:

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

Ich denke, die Vorteile wären die Annotation, die im typeAdapter verwendet wird. Ich möchte herausfinden, ob es Leistungssteigerungen gibt, wenn ich zu Moshi wechsle.

j2emanue
quelle

Antworten:

94

Moshi verwendet Okio, um einige Dinge zu optimieren, die Gson nicht tut.

  • Beim Lesen von Feldnamen muss Moshi keine Zeichenfolgen zuweisen oder Hash-Lookups durchführen.
  • Moshi scannt die Eingabe als eine Folge von UTF-8-Bytes und konvertiert sie träge in Java-Zeichen. Beispielsweise müssen niemals ganzzahlige Literale in Zeichen konvertiert werden.

Die Vorteile dieser Optimierungen sind besonders ausgeprägt, wenn Sie bereits Okio-Streams verwenden. Benutzer von Retrofit und OkHttp profitieren insbesondere von Moshi.

Weitere Diskussionen über die Ursprünge von Moshi finden Sie in meinem Beitrag Moshi, einem anderen JSON-Prozessor .

Jesse Wilson
quelle
Verwendet es Reflexion
j2emanue
2
@ j2emanue Als Implementierungsdetail setzen die Standard-JsonAdapters für Ihre benutzerdefinierten Klassen Felder mit Reflexion.
Eric Cochran
1
@ j2emanue Reflexion kann vermieden werden, indem codegen github.com/square/moshi#codegen
Pedro Lopes
34

Laut dem Kommentar von swankjesse zu reddit :

Ich bin stolz auf meine Arbeit an Gson, aber auch enttäuscht über einige seiner Einschränkungen. Ich wollte diese ansprechen, aber nicht als "Gson 3.0", auch weil ich nicht mehr bei Google arbeite. Jake, Scott, Eric und ich haben Moshi geschaffen, um die verschiedenen Einschränkungen von Gson anzugehen. Hier sind zehn kleine Gründe, Moshi Gson vorzuziehen:

  1. Kommende Kotlin-Unterstützung.

  2. Qualifizierer wie @HexColor int ermöglichen mehrere JSON-Darstellungen für einen einzelnen Java-Typ.

  3. Mit @ToJson und @FromJson können Sie auf einfache Weise benutzerdefinierte JSON-Adapter schreiben und testen.

  4. Mit JsonAdapter.failOnUnknown () können Sie unerwartete JSON-Daten ablehnen.

  5. Vorhersehbare Ausnahmen. Moshi löst IOException bei E / A-Problemen und JsonDataException bei Typinkongruenzen aus. Gson ist überall.

  6. JsonReader.selectName () vermeidet im allgemeinen Fall unnötige UTF-8-Decodierung und String-Zuweisungen.

  7. Sie versenden eine kleinere APK. Gson ist 227 KiB, Moshi + Okio zusammen sind 200 KiB.

  8. Moshi wird keine Implementierungsdetails von Plattformtypen in Ihren codierten JSON verlieren. Das macht mir Angst vor Gson: gson.toJson (SimpleTimeZone.getTimeZone ("GMT"))

  9. Moshi macht standardmäßig kein seltsames HTML-Escape. Ein Beispiel finden Sie in Gsons Standardcodierung "12 & 5 = 4".

  10. Standardmäßig ist kein defekter Datumsadapter installiert.

Wenn Sie neuen Code schreiben, empfehle ich dringend, mit Moshi zu beginnen. Wenn Sie bereits ein Projekt mit Gson haben, sollten Sie ein Upgrade durchführen, wenn dies einfach und nicht riskant ist. Ansonsten bleib bei Gson! Ich gebe mein Bestes, um sicherzustellen, dass es kompatibel und zuverlässig bleibt.

Ahamadullah Saikat
quelle
1

Aus dem vorherigen Link können Sie ersehen, dass durch die Verwendung von moshi codegen Kompilierungszeitadapter für Modellklassen erstellt werden, wodurch die Verwendung von Reflektion zur Laufzeit entfällt

Modell

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

app / build.gradle

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

Generiert eine MyModelJsonAdapter-Klasse mit Validierungen, um die Nullfähigkeit der Modelleigenschaften sicherzustellen.

Ihr Mann
quelle
Würden Sie nicht sagen, dass Moshi dann schneller ist?
j2emanue