Moshi vs Gson na Androidzie [zamknięte]

81

Decyduję, czy użyć Moshi by square czy Gson do serializacji i deserializacji danych modelu.

jedną rzeczą, której zawsze nie lubiłem w Gson, jest to, że myślę, że używa odbicia, które może być powolne na Androidzie? Czy Moshi również używa refleksji?

Jakie są zalety i wady Moshi vs Gson?

Widzę je jako podobne. Weźmy na przykład to stwierdzenie, które tworzy pliktypeAdapter:

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

i żeby go użyć zarejestruj tak jak w gson:

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

Myślę, że zaletą byłaby adnotacja używana w typeAdapter. Chcę się dowiedzieć, czy po przejściu na Moshi będzie jakikolwiek wzrost wydajności.

j2emanue
źródło

Odpowiedzi:

94

Moshi używa Okio do optymalizacji kilku rzeczy, których Gson nie robi.

  • Podczas czytania nazw pól Moshi nie musi przydzielać ciągów ani wyszukiwać skrótów.
  • Moshi skanuje dane wejściowe jako sekwencję bajtów UTF-8, leniwie konwertując na znaki Java. Na przykład nigdy nie musi konwertować literałów całkowitych na znaki.

Korzyści płynące z tych optymalizacji są szczególnie widoczne, jeśli korzystasz już ze strumieni Okio. Szczególnie użytkownicy Retrofit i OkHttp korzystają z Moshi.

Dalsza dyskusja na temat pochodzenia Moshi znajduje się w moim poście, Moshi, innym procesorze JSON .

Jesse Wilson
źródło
Czy używa refleksji
j2emanue,
2
@ j2emanue Jako szczegół implementacji, domyślne JsonAdapters dla klas niestandardowych ustawią pola z odbiciem.
Eric Cochran
1
@ j2emanue Refleksji można uniknąć, używając codegen github.com/square/moshi#codegen
Pedro Lopes
35

Zgodnie z komentarzem swankjesse na reddicie :

Jestem dumny z mojej pracy nad Gsonem, ale też rozczarowany niektórymi jego ograniczeniami. Chciałem się do nich odnieść, ale nie jako „Gson 3.0”, po części dlatego, że nie pracuję już w Google. Jake, Scott, Eric i ja stworzyliśmy Moshi, aby zająć się różnymi ograniczeniami Gson. Oto dziesięć małych powodów, dla których warto preferować Moshi od Gson:

  1. Nadchodzące wsparcie Kotlin.

  2. Kwalifikatory, takie jak @HexColor int, pozwalają na wiele reprezentacji JSON dla jednego typu Java.

  3. @ToJson i @FromJson ułatwiają pisanie i testowanie niestandardowych adapterów JSON.

  4. JsonAdapter.failOnUnknown () umożliwia odrzucanie nieoczekiwanych danych JSON.

  5. Przewidywalne wyjątki. Moshi zgłasza wyjątek IOException w przypadku problemów we / wy i wyjątek JsonDataException w przypadku niezgodności typów. Gson jest wszędzie.

  6. JsonReader.selectName () pozwala uniknąć niepotrzebnego dekodowania UTF-8 i alokacji ciągów w typowym przypadku.

  7. Wyślesz mniejszy plik APK. Gson to 227 KiB, Moshi + Okio razem to 200 KiB.

  8. Moshi nie spowoduje wycieku szczegółów implementacji typów platform do zakodowanego JSON. Boję się Gson: gson.toJson (SimpleTimeZone.getTimeZone ("GMT"))

  9. Moshi nie wykonuje domyślnie dziwnych znaków ucieczki HTML. Spójrz na przykład na domyślne kodowanie GSona „12 i 5 = 4”.

  10. Domyślnie nie zainstalowano uszkodzonej karty Data.

Jeśli piszesz nowy kod, bardzo polecam zacząć od Moshi. Jeśli masz istniejący projekt z Gson, powinieneś uaktualnić, jeśli będzie to proste i nie ryzykowne. W przeciwnym razie trzymaj się Gson! Robię co w mojej mocy, aby był kompatybilny i niezawodny.

Ahamadullah Saikat
źródło
1

Z poprzedniego linku widać, że użycie moshi codegen utworzy adaptery czasu kompilacji do klas modelu, co usunie użycie odbicia w czasie wykonywania

Model

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

app / build.gradle

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

Wygeneruje klasę MyModelJsonAdapter z walidacjami, aby zapewnić zerową wartość właściwości modelu.

Hermandroid
źródło
nie sądzisz, że wtedy moshi jest szybszy?
j2emanue