私のタイプミスマッチの問題を解決するには Deserializers
を作成し、ObjectMapper
に追加しました。しかし、これにより性能が著しく低下します。カスタムデシリアライザでデシリアライズすると、多くのGC呼び出しが発生し、時間がかかります
デフォルトのデシリアライザでは、logcat
で1-2ガベージコレクションコールが発生し、カスタムデシリアライザでは少なくとも7-8 GCコールがあるため、処理時間も大幅に増加します。
マイデシリアライザ:
public class Deserializer<T> {
public JsonDeserializer<T> getDeserializer(final Class<T> cls) {
return new JsonDeserializer<T>(){
@Override
public T deserialize(JsonParser jp, DeserializationContext arg1) throws IOException, JsonProcessingException {
JsonNode node = jp.readValueAsTree();
if (node.isObject()) {
return new ObjectMapper().convertValue(node, cls);
}
return null;
}
};
}
}
そして、私は
public class DeserializerAttachedMapper<T> {
public ObjectMapper getMapperAttachedWith(final Class<T> cls , JsonDeserializer<T> deserializer) {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule(deserializer.toString(), new Version(1, 0, 0, null, null, null));
module.addDeserializer(cls, deserializer);
mapper.registerModule(module);
return mapper;
}
}
EDITマッパーに追加するためにこれを使用しています:が追加されました余分なデータ
私のJSONはかなりの大きさが、巨大ではないのです: 貼り付け済みit here
は今、私はこのコードを使用する場合、同じJSONを解析するために:
String response = ConnectionManager.doGet(mAuthType, url, authToken);
FLog.d("location object response" + response);
// SimpleModule module = new SimpleModule("UserModule", new Version(1, 0, 0, null, null, null));
// JsonDeserializer<User> userDeserializer = new Deserializer<User>().getDeserializer(User.class);
// module.addDeserializer(User.class, userDeserializer);
ObjectMapper mapper = new ObjectMapper();
// mapper.registerModule(module);
JsonNode tree = mapper.readTree(response);
Integer code = Integer.parseInt(tree.get("code").asText().trim());
if(Constants.API_RESPONSE_SUCCESS_CODE == code) {
ExploreLocationObject locationObject = mapper.convertValue(tree.path("response").get("locationObject"), ExploreLocationObject.class);
FLog.d("locationObject" + locationObject);
FLog.d("locationObject events" + locationObject.getEvents().size());
return locationObject;
}
return null;
はその後、私のlogcatはlike this
である。しかし、私は同じJSONのためにこのコードを使用している場合
String response = ConnectionManager.doGet(mAuthType, url, authToken);
FLog.d("location object response" + response);
SimpleModule module = new SimpleModule("UserModule", new Version(1, 0, 0, null, null, null));
JsonDeserializer<User> userDeserializer = new Deserializer<User>().getDeserializer(User.class);
module.addDeserializer(User.class, userDeserializer);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
JsonNode tree = mapper.readTree(response);
Integer code = Integer.parseInt(tree.get("code").asText().trim());
if(Constants.API_RESPONSE_SUCCESS_CODE == code) {
ExploreLocationObject locationObject = mapper.convertValue(tree.path("response").get("locationObject"), ExploreLocationObject.class);
FLog.d("locationObject" + locationObject);
FLog.d("locationObject events" + locationObject.getEvents().size());
return locationObject;
}
return null;
はその後、私のlogcatですlike this
1件の追加コメント:あなたが行われる必要があり、次のコードで あなたは再利用し、絶対に確認してください 'ObjectMapper' - それは重いオブジェクトで、リクエストごとに一度に作成するべきではありません。さもなければ、それは間違いなく多くのGC活動を引き起こす可能性がある。上記のコードだけでは分かりません。 – StaxMan
実際、あなたのデシリアライザがObjectMapperを作成していることに気付きました。これは非常にコストがかかります。 'JsonParser 'を使うことでそれを避けることができます。getCodec() 'を呼び出し、結果をObjectMapper(安全なアップキャスト)にキャストします。それもかなり助けになるはずです。 – StaxMan
自分のコードを修正してオブジェクトマッパーをシングルトンに追加したところ、デフォルトのデシリアライザのパフォーマンスは向上しましたが、カスタムデシリアライザの問題はまだ残っています。また、同じモジュールに2つのデシリアライザを追加すると、デフォルトのデシリアライザがカスタムのデシリアライザと呼ばれることに気付きました。 'JsonParser.getCodec()'は静的メソッドではないので、リクエストごとに 'JsonParser'を作成する必要があります。それはあまりにも高価ではないでしょうか? – vKashyap