【问题标题】:startswith vs JSON deserialization performance?开始与 JSON 反序列化性能?
【发布时间】:2014-01-24 08:46:02
【问题描述】:

我正在做一个项目,在该项目中我正在对我的服务器进行休息 url 调用,这会返回一个 JSON 字符串作为响应。如果服务有任何问题,那么它会给我以下 JSON 字符串中的任何一个作为错误响应 -

{"error":"no user_id passed"}

or

{"warning": "user_id not found", "user_id": some_user_id}

or

{"error": "user_id for wrong partition", "user_id": some_user_id, "partition": some_partition}

or

{"error":"no client_id passed"}

or

{"error": "missing client id", "client_id":2000}

但如果是成功响应,那么我将返回 json 字符串作为 -

{"@data": {"oo":"1205000384","p":"2047935"} 

下面是我用来调用的代码,如果服务端出现问题或成功,response 变量将具有上述 JSON 字符串。

RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);

// here response has the JSON string

ClientResponse clientResponse = checkJSONResponse(response);

return clientResponse;

目前我正在返回响应,而不检查任何内容。但是现在我正在考虑验证响应并查看它是否是错误,然后将其记录为特定错误,如果是成功响应,则返回它。

第一个选项:- 那么我是不是应该每次调用都反序列化上面的jsonresponseString,然后看是成功还是错误响应。

第二个选项:- 或者我应该只检查响应字符串是否以错误或警告开头,如果它以错误或警告开头,则反序列化响应并提取特定的错误消息。

因为在大多数情况下,我们将获得返回数据的成功响应,并且只有大约 2% 我们将获得高于错误响应的返回,所以我认为每次反序列化只是为了仅提取错误情况将是昂贵的startsWith错误或警告选项然后反序列化?

第一个选项-

private ClientResponse checkJSONResponse(final String response) throws Exception {

Gson gson = new Gson();
ClientResponse clientResponse = null;
JsonObject jsonObject = gson.fromJson(response, JsonObject.class); // parse
if (jsonObject.has("error") || jsonObject.has("warning")) {

    final String error = jsonObject.get("error") != null ? jsonObject.get("error").getAsString() : jsonObject
        .get("warning").getAsString();

    // log error here
    ClientResponse clientResponse = new ClientResponse(response, "ERROR_OCCURED", "SUCCESS");
} else {
    ClientResponse clientResponse = new ClientResponse(response, "NONE", "SUCCESS");
}

    return clientResponse;
}

第二个选项-

private ClientResponse checkJSONResponse(final String response) throws Exception {

Gson gson = new Gson();
ClientResponse clientResponse = null;
if(response.startsWith("{\"error\":") || response.startsWith("{\"warning\":")) {
    JsonObject jsonObject = gson.fromJson(response, JsonObject.class); // parse
    if (jsonObject.has("error") || jsonObject.has("warning")) {

        final String error = jsonObject.get("error") != null ? jsonObject.get("error").getAsString() : jsonObject
            .get("warning").getAsString();

        // log error here with specific messages
        ClientResponse clientResponse = new ClientResponse(response, "ERROR_OCCURED", "SUCCESS");
    }
} else {
        ClientResponse clientResponse = new ClientResponse(response, "NONE", "SUCCESS");
    }

    return clientResponse;
}

对于我的用例,这里的最佳选择是什么?我主要是从性能角度看哪个选项会更有效率?

【问题讨论】:

    标签: java json deserialization gson startswith


    【解决方案1】:

    第一个显然更好。你所做的被称为premature optimization。你的第二种情况很容易出错,想象一下如果重新排序元素会发生什么。在确定这是瓶颈之前不要进行优化。

    UPD:如果您分析了您的代码并发现无用的对象解析确实是一个问题。您可以分配错误代码,而不是传递字符串值并使用lastIndexOf() 方法而不是startsWith()。这样可以防止您出现对象重新排序问题,但可以保证警告消息中不存在“错误”字样。

    【讨论】:

    • 感谢 Mikhail 的建议。在我的场景中,元素不会被重新排序。为什么我这么好奇,因为我们对此有非常严格的延迟要求。我最近添加了这个代码所以想了解这是否会对性能产生任何影响..
    猜你喜欢
    • 2016-09-10
    • 2021-11-14
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多