English 中文(简体)
GSON 序列化非常慢
原标题:GSON Serialization very very slow

我试图使用GSON将7000 POJO的阵列序列化,而序列化时间极为缓慢。

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, Type typeOfSrc, 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序列器测试性能,我测试了以下代码,它可以比GSON大约快10x的同一组Case天体序列。

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

知道Gsonson为什么在这个案子里表现这么差吗?

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

富尔在哪里:

public class Foo {
public Long id;
}

这一产出:

Serialization time using Gson: 0.233
Serialization time using org.json: 0.028
true

近10x的性能差异!

最佳回答

我试图复制您的问题, 但无法复制。 我创建了 7000 个天体, 其中含有非技术性的数据 。 在我的想法Pad 中, 它用 Gson ~ 260 ms 将 Gson 的 ~ 3MB 序列成序列, 这个 Gson 的 ~ 10Mbps 是一个值得尊敬的 ~ 10Mbps 。

其中很大一部分时间用于将日期转换为字符串。将两个日期字段转换为长期保存的大约50米。

我从树的调适器(JsonSregiz/JsonDesericer)迁移到新的流适器等级TypeAdaper ,从而节省了另外的~10米。

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

我的假想和你的假想之间的主要区别是 我用的是我自己的假钥匙类。但如果钥匙是瓶颈的话, 当你手动对每个案子进行序列处理时,你应该会发现这个瓶颈。

<强 > 解决问题

您的下一个最佳步骤是将字段从 < code> Case 中删除, 直到序列化改善。 您的字段之一可能包含一些需要很长时间才能序列化的东西: 也许是一个非常长的字符串, 需要过度逃跑? 一旦您孤立了问题 < a href=> http://code.google. com/ p/google-gson/issues/list" rel= “ noreferrer” > 向 Gson 工程报告一个错误 < /a >, 我们将会很高兴地解决这个问题。 除了包含包含复制问题的 < em> em > 代码 外, 您还应该包含代表 < em > data < / em > 。

问题回答




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签