关于JSONObject的性能问题

现有一段代码:

private JSONObject override(User user, UserVO vo) {
String json = JSON.toJSONString(vo);
JSONObject o = JSON.parseObject(json);
JSONObject name = new JSONObject();
if (StringUtils.isNotBlank(user.getName())) {
name = JSON.parseObject(user.getName());
o.put("name", name);
}
}

这段代码就是将一个VO对象转JSON字符串之后再转为对象,然后将User对象中的name属性转为对象,最后通过put方法获取到这个它。

 

其实这个逻辑是没问题的,不过我们可以尝试测试它的运行速度,

这是一段简单的测试代码:

public static void main(String[] args) {
    User user = new User();
    long start = System.currentTimeMillis();
    String json = JSON.toJSONString(user);
    JSONObject o = JSON.parseObject(json);
    long end = System.currentTimeMillis();
    System.out.println("用时:"+(end - start) + "ms");
}

为了避免测试偶然性,采用多次测试:

第一次:331ms

第二次:348ms

第三次:367ms

第四次:328ms

第五次:307ms

第六次:383ms

可以发现,就这样一个简单的转换,竟然用时在300ms以上。

点进 parseObject() 查看原因:

public static JSONObject parseObject(String text) {
        Object obj = parse(text);
        if (obj instanceof JSONObject) {
            return (JSONObject)obj;
        } else {
            try {
                return (JSONObject)toJSON(obj);
            } catch (RuntimeException var3) {
                throw new JSONException("can not cast to JSONObject.", var3);
            }
        }
}

方法内第一行开始解析传入的参数,再往里面点,发现仅仅一步解析,就走了很多方法。

然后是toJSON():

    public static Object toJSON(Object javaObject, SerializeConfig config) {
        if (javaObject == null) {
            return null;
        } else if (javaObject instanceof JSON) {
            return javaObject;
        } else {
            JSONObject json;
            int len;
            if (javaObject instanceof Map) {
                Map<Object, Object> map = (Map)javaObject;
                len = map.size();
                Object innerMap;
                if (map instanceof LinkedHashMap) {
                    innerMap = new LinkedHashMap(len);
                } else if (map instanceof TreeMap) {
                    innerMap = new TreeMap();
                } else {
                    innerMap = new HashMap(len);
                }

                json = new JSONObject((Map)innerMap);
                Iterator var24 = map.entrySet().iterator();

                while(var24.hasNext()) {
                    Entry<Object, Object> entry = (Entry)var24.next();
                    Object key = entry.getKey();
                    String jsonKey = TypeUtils.castToString(key);
                    Object jsonValue = toJSON(entry.getValue(), config);
                    json.put(jsonKey, jsonValue);
                }

                return json;
            } else {
                Object item;
                if (javaObject instanceof Collection) {
                    Collection<Object> collection = (Collection)javaObject;
                    JSONArray array = new JSONArray(collection.size());
                    Iterator var19 = collection.iterator();

                    while(var19.hasNext()) {
                        Object item = var19.next();
                        item = toJSON(item, config);
                        array.add(item);
                    }

                    return array;
                } else if (javaObject instanceof JSONSerializable) {
                    String json = toJSONString(javaObject);
                    return parse(json);
                } else {
                    Class<?> clazz = javaObject.getClass();
                    if (clazz.isEnum()) {
                        return ((Enum)javaObject).name();
                    } else if (clazz.isArray()) {
                        len = Array.getLength(javaObject);
                        JSONArray array = new JSONArray(len);

                        for(int i = 0; i < len; ++i) {
                            item = Array.get(javaObject, i);
                            Object jsonValue = toJSON(item);
                            array.add(jsonValue);
                        }

                        return array;
                    } else if (ParserConfig.isPrimitive2(clazz)) {
                        return javaObject;
                    } else {
                        ObjectSerializer serializer = config.getObjectWriter(clazz);
                        if (serializer instanceof JavaBeanSerializer) {
                            JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer)serializer;
                            json = new JSONObject();

                            try {
                                Map<String, Object> values = javaBeanSerializer.getFieldValuesMap(javaObject);
                                Iterator var7 = values.entrySet().iterator();

                                while(var7.hasNext()) {
                                    Entry<String, Object> entry = (Entry)var7.next();
                                    json.put((String)entry.getKey(), toJSON(entry.getValue(), config));
                                }

                                return json;
                            } catch (Exception var11) {
                                throw new JSONException("toJSON error", var11);
                            }
                        } else {
                            String text = toJSONString(javaObject);
                            return parse(text);
                        }
                    }
                }
            }
        }
    }

可以发现里面嵌套了4层if-else语句,逻辑十分复杂,甚至还有递归方法。

 

所以 parseObject() 方法的执行效率很低,如果出现高并发的情况,那很可能直接崩溃。

posted @ 2020-10-13 17:43  LonZyuan  阅读(5137)  评论(0编辑  收藏  举报