【问题标题】:How to avoid unnecessary object creation in Java in a for loop如何避免在 for 循环中在 Java 中创建不必要的对象
【发布时间】:2015-09-30 10:29:00
【问题描述】:

我正在使用 java 创建以下 json 文件

JSONObject json = new JSONObject();
JSONArray vertex = new JSONArray();
for (int i = 0; i < num; i++) {
    JSONObject usr1 = new JSONObject();
    JSONObject usr2 = new JSONObject();

    // String na="name"+i
    usr1.put("type", "string");
    usr1.put("value", "name" + i);
    usr2.put("name", usr1);

    usr2.put("_id", Integer.toString(i));
    usr2.put("_type", "vertex");
    // v2.put(usr2);
    vertex.put(usr2);

    // email
    JSONObject usr3 = new JSONObject();
    JSONObject usr4 = new JSONObject();
    usr3.put("type", "string");
    usr3.put("value", "email" + i + "@gmail.com");
    usr4.put("email", usr3);

    usr4.put("_id", Integer.toString(i + num));
    usr4.put("_type", "vertex");
    vertex.put(usr4);
}
json.put("vertex", vertex);

num 可以约为 60,000-200,000。

但是在这里我一次又一次地创建 java 对象,这非常昂贵。我希望最小化对象的创建,并且不想过多地更改代码结构。如何在不过多更改代码结构的情况下实现这一点?

我正在使用来自org.codehaus.jettison.json 包的 JSON* 类。我必须将它写入 json 对象的文件

【问题讨论】:

  • 我没明白你的意思?
  • 其实并不贵。如果您认为自己有性能问题(未说明),请分析您的代码以找出瓶颈所在。您几乎肯定会感到惊讶。
  • 您关心的应该是代码如何接近实现所需的业务逻辑。一旦你确定你写了一段相关的代码,你就不应该被潜在的昂贵操作所困扰。当您注意到这些昂贵的操作导致性能下降时,您可能会对此感到困扰。
  • 为什么不从删除 v2xyz 的定义开始,因为创建的对象根本没有被使用?
  • 这个问题是在 num=20000 之后它停止工作;

标签: java json oop object


【解决方案1】:

为了在不创建中间对象的情况下快速生成 JSON,可以使用 JSONWriter

StringWriter sw = new StringWriter();
JSONWriter writer = new JSONWriter(sw);
writer.object().key("vertex").array();
for (int i = 0; i < num; i++) {
    writer
        .object() // usr2
            .key("name")
                .object() // usr1
                    .key("type").value("string")
                    .key("value").value("name"+i)
                .endObject()
            .key("_id").value(Integer.toString(i))
            .key("_type").value("vertex")
        .endObject()
        .object() // usr4
            .key("email")
                .object() // usr3
                    .key("type").value("string")
                    .key("value").value("email"+i+"@gmail.com")
                .endObject()
            .key("_id").value(Integer.toString(i+num))
            .key("_type").value("vertex")
        .endObject();
}
writer.endArray().endObject();
String json = sw.toString();

这里 StringWriter 用于存储中间 JSON 文本。或者,您可以直接写入文件或网络套接字,而不将其保存在内存中。

【讨论】:

    【解决方案2】:

    你的 json 好像是这样的

    {
    "vertex": [
        {
            "name": {
                "type": "string",
                "value": "name0"
            },
            "_id": 0,
            "_type": "vertex"
        },
        {
            "email": {
                "type": "string",
                "value": "email0@gmail.com"
            },
            "_id": 0,
            "_type": "vertex"
        },
        .....
    ]
    }
    

    在每个连续的循环中... 2 jsonobject 被设置在顶点 json 数组上... 您可以将大小减少一半...通过在每个连续循环中创建 1 个 jsonobject

    类似的东西

    {
    "vertex": [
        {
            "_id": 0,
            "_type": "vertex",
            "name": "name0",
            "email": "email0@gmail.com"
        },
        ....
    ]
    }
    

    你不会在创建 json 方面做太多...

    虽然我也找不到包含“_id”和“_type”键的意义......因为“_id”包含从 0 到 num 的索引,您可以使用顶点数组获取该索引...

    因此你可以使用json的结构作为

    {
    "vertex": [
      {
        "name": "name0",
        "email": "email0@gmail.com"
      },
      ....
    ]
    }
    

    你的java代码可能会减少到这个......

    JSONObject json = new JSONObject();
    JSONArray vertex = new JSONArray();
    for (int i = 0; i < num; i++) {
       vertex.put(new JSONObject().put("name", "name" + i).put("email", "email" + i + "@gmail.com"));
    }
    json.put("vertex", vertex);
    

    【讨论】:

    • 但是如果你循环运行 20,000 到 30,000,java eclipse 会挂掉
    • 你能告诉我那个手术所用的时间吗?
    猜你喜欢
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    • 2012-07-23
    相关资源
    最近更新 更多