java – GSON序列化非常慢
我试图使用GSON序列化一个7000 POJO阵列,并且序列化时间非常慢.序列化以下对象的数组是3-5秒的顺序:
public class Case { private Long caseId; private Key<Organization> orgKey; private Key<Workflow> workflowKey; private Key<User> creatorKey; private Date creationTimestamp; private Date lastUpdatedTimestamp; private String name; private String stage; private String notes; } 关键字段使用自定义序列化器/解串器序列化: public class GsonKeySerializerDeserializer implements JsonSerializer<Key<?>>,JsonDeserializer<Key<?>>{ @Override public JsonElement serialize(Key<?> src,Type typeOfSrc,JsonSerializationContext arg2) { return new JsonPrimitive(src.getString()); } @Override public Key<?> deserialize(JsonElement src,JsonDeserializationContext arg2) throws JsonParseException { if (src.isJsonNull() || src.getAsString().isEmpty()) { return null; } String s = src.getAsString(); com.google.appengine.api.datastore.Key k = KeyFactory.stringToKey(s); return new Key(k); } } 为了测试性能,手工编写一个JSON序列化程序,我测试了以下代码,它可以将相同的Case对象数组序列化大约比GSON快10倍. List<Case> cases = (List<Case>) retVal; JSONArray a = new JSONArray(); for (Case c : cases) { JSONObject o = new JSONObject(); o.put("caseId",c.getCaseId()); o.put("orgKey",c.getOrgKey().getString()); o.put("workflowKey",c.getWorkflowKey().getString()); o.put("creatorKey",c.getCreatorKey().getString()); o.put("creationTimestamp",c.getCreationTimestamp().getTime()); o.put("lastUpdatedTimestamp",c.getLastUpdatedTimestamp().getTime()); o.put("name",c.getName()); o.put("stage",c.getStage()); o.put("notes",c.getNotes()); a.put(o); } String json = a.toString(); 为什么GSON在这种情况下表现如此糟糕? UPDATE 以下是实际启动序列化的代码: Object retVal = someFunctionThatReturnsAList(); String json = g.toJson(retVal); resp.getWriter().print(json); UPDATE2 这是一个非常简单的测试用例,说明了相对于org.json的性能不佳: List<Foo> list = new ArrayList<Foo>(); for (int i = 0; i < 7001; i++) { Foo f = new Foo(); f.id = new Long(i); list.add(f); } Gson gs = new Gson(); long start = System.currentTimeMillis(); String s = gs.toJson(list); System.out.println("Serialization time using Gson: " + ((double) (System.currentTimeMillis() - start) / 1000)); start = System.currentTimeMillis(); JSONArray a = new JSONArray(); for (Foo f : list) { JSONObject o = new JSONObject(); o.put("id",f.id); a.put(o); } String json = a.toString(); System.out.println("Serialization time using org.json: " + ((double) (System.currentTimeMillis() - start) / 1000)); System.out.println(json.equals(s)); Foo在哪里 public class Foo { public Long id; } 输出: Serialization time using Gson: 0.233 Serialization time using org.json: 0.028 true 几乎10倍的性能差异! 解决方法
我试图重现你的问题,不能.我在其中创建了7000个具有非平凡数据的对象.在我的ThinkPad上,Gson?260ms串行化?3MB的Gson,这是一个可观的?10Mbps.
大部分时间用于将日期转换为字符串.将两个日期字段转换为“长”保存约50ms. 通过从树型适配器(JsonSerializer / JsonDeserializer)迁移到新的流式适配器ClassAdaper类,我可以保存另外约10ms.设置此代码的代码如下所示: private static TypeAdapter<Key<String>> keyAdapter = new TypeAdapter<Key<String>>() { @Override public void write(JsonWriter out,Key<String> value) throws IOException { out.value(value.value); } @Override public Key<String> read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } return new Key<String>(in.nextString()); } }; ... Gson gson = new GsonBuilder() .registerTypeAdapter(Key.class,keyAdapter) .create(); 我的场景与你的主要区别在于我使用自己的虚假Key类.但是,如果Key是手动序列化每个案例时应该出现的瓶颈. 解决问题 最好的下一步是从Case中删除字段,直到序列化改进.您的一个字段可能包含长时间序列化的东西:也许是一个需要过多转义的长字符串?一旦将问题report a bug与Gson项目隔离开来,我们将很乐意解决问题.除了包含重现问题的代码之外,还应包括代表性数据. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java.lang.IllegalArgumentException:观察者为null
- Java实现打飞机小游戏(附完整源码)
- javaweb05 文件的上传一
- java – 如何将JSF消息编码设置为UTF-8?
- 有任何教程可以理解Streams,Buffers及其在Java中的用法吗?
- java – 在执行Html.fromHtml后更改TextViews中的html链接样
- 在抽象类java中调用非抽象方法
- [Java拾遗四]JavaWeb基础之Servlet_Request&&Respo
- Spring Boot中整合Spring Security并自定义验证代码实例
- 全面解释java中StringBuilder、StringBuffer、String类之间