我在从String节点创建JSON时遇到了问题。
目前我是用node.toString()方法做的。但有时,这需要7-8秒才能创建加权为15MB-18MB的JSON字符串。
我也尝试了mapper.writeValueAsString(node))方法。但它显示了一些额外的时间来测试。这是很难检查的问题,因为它也是很难复制。
我目前只使用ObjectNode (不使用TextNode、BooleanNode等),这会对此产生影响吗?或者是否有更好的方法将JSONNode转换为String?
示例代码: JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
ObjectNode node = nodeFactory.objectNode();
node.put("fnm", "Namal");
node.put("lnm", "Fernando");
node.put("age", 30);
for (int i = 0; i < 10000; i++) {
ObjectNode order = nodeFactory.objectNode();
order.put("id", (i+1000)+"");
order.put("nm", "ORD"+(i+1000));
order.put("ref", "RF-"+i);
node.put("order"+i, order);
}
long smili = System.currentTimeMillis();
System.out.println("main().Node : " + node.toString());
System.out.println("main().TIMING 1 : " + (System.currentTimeMillis() - smili) / 1000.0);;
long smili2 = System.currentTimeMillis();
ObjectMapper mapper = new ObjectMapper();
System.out.println("main().Node : " + mapper.writeValueAsString(node));
System.out.println("main().TIMING 2 : " + (System.currentTimeMillis() - smili2) / 1000.0);;发布于 2015-07-20 23:28:31
首先要做的事情是:永远不要将JsonNode.toString()用于序列化。它对于简单的故障排除很有用,但是由于它没有访问上下文配置的权限,所以它不一定会产生有效的JSON。这是故意的。相反,您应该使用ObjectMapper或ObjectWriter对其进行序列化;这将使用映射程序所具有的精确配置和设置(或由映射器创建的编写器)生成有效的JSON。
现在:您的时间比较是有缺陷的,因为您只使用ObjectMapper进行一次调用。在最初的N次调用中存在开销;部分原因是ObjectMapper初始化,部分原因是JVM预热(运行优化的动态JIT编译器等等)。要获得更多可用的结果,您需要多次调用方法,最好让它运行几秒钟。
但除此之外,一个常见的问题是忘记有足够的堆空间。在Java中,String至少需要相当于2x字符串长度的内存(每个char需要2个字节)。但这只是结果的大小;在序列化期间,还需要一个临时缓冲区,使用大致相当的数量。然而,在磁盘上,UTF-8编码通常每个字符只使用一个字节(对于ASCII字符).
因此,假设您看到一个15 mB的文件,它可以在处理过程中使用60 mB的内存。如果您的堆大小设置为小(例如,64 megs,这在许多情况下是默认的),则会导致非常繁重的垃圾收集处理。解决方案是要么增加堆大小。或者,除非您确实需要字符串,否则:
File或网络连接,则使用中间File是一种反模式。byte[]:这将只需要与文件相同的内存(因为它是在内存中编码的UTF-8,而不是包装好的char[] )。https://stackoverflow.com/questions/31514785
复制相似问题