首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加速BufferedWriter

加速BufferedWriter
EN

Code Review用户
提问于 2015-10-20 18:22:34
回答 2查看 2.2K关注 0票数 4

我可以对以下方法进行任何速度改进吗?它接受一个JDBC ResultSet并将其分解为几个CSV文件:

代码语言:javascript
复制
public static void convertToCSV(final ResultSet rs) throws SQLException, IOException {
    final DateFormat format = new SimpleDateFormat("yyyyMMdd,HH:mm:ss");
    format.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
    final StringBuilder sb = new StringBuilder();
    while (rs.next()) {
        final File file = new File(sb.append(rs.getString("FIELD1")).append(".csv").toString());
        if (!file.exists()) {
            file.createNewFile();
        }
        final BufferedWriter fw = new BufferedWriter(new FileWriter(file.getAbsoluteFile(), true));
        fw.write(rs.getString("FIELD2"));
        fw.write(',');
        fw.write(rs.getString("FIELD3"));
        fw.write(',');
        final String clobValue = rs.getString("FIELD4");
        if(clobValue==null)
            fw.write("null,");
        else{
            fw.write('\"');
            fw.write(clobValue);
            fw.write("\",");
        }
        final Date date = new Date(rs.getLong("FIELD5"));
        fw.write(format.format(date));
        fw.write('\n');
        fw.close();
        sb.setLength(0);
    }
    rs.close();
}
EN

回答 2

Code Review用户

发布于 2015-10-20 18:51:18

通过添加多线程支持,您可能会看到性能提高。对于每一行,创建一个自定义Runable的实例,该实例接受这五个值并将其添加到ThreadPoolExecutor中。你可以用游泳池的大小来打发时间。与所有性能增强一样,您将需要测试、测试、测试以确保您看到了真正的好处,并且您确实需要在生产克隆上进行测试才有任何意义。这可能对您的本地机器没有什么影响,但对生产有很大帮助,反之亦然。

您对StringBuilder的使用(而不是仅仅串联)可能对您没有任何好处。编译器将完成这一工作,而且代码更难按原样读取。还有其他的事情要挑,但没有一个是性能相关的。

票数 2
EN

Code Review用户

发布于 2015-10-21 01:45:54

如果您使用的是Java 7,则应该在try-with-resources实例上使用BufferedWriter来实现安全和高效的I/O管理。

由于您只使用StringBuilder一次来创建文件名,您还可以考虑简单的String连接:

代码语言:javascript
复制
File file = new File(rs.getString("FIELD1") + ".csv");

这是一个StringBuilder实例与可读性略有提高之间的权衡。:)

您也可以考虑先构造输出fw.write(),而不是多次调用String。然后,如果您碰巧在Java8上,您可以考虑使用Collectors.joining(CharSequence)来加入您需要的输出值的Stream

代码语言:javascript
复制
// using Java 8's optional to slightly simplify the transformation
String clobValue = Optional.ofNullable(rs.getString("FIELD4"))
                            .map(v -> "\"" + v + "\"").orElse(null);
String date = format.format(new Date(rs.getLong("FIELD5")));
String output = Arrays.asList(rs.getString("FIELD2"), rs.getString("FIELD3"), 
                    clobValue, date).stream().collect(Collectors.joining(","));
fw.append(output).newLine();

最后,我同意@EricStein的S的回答,如果您真的需要使用最多11,您可能需要考虑多线程。在这一点上,您可能希望为来自ResultSet对象的值应用一个简单的模型类,以便您可以处理来自List<FileContent>的多线程。例如:

代码语言:javascript
复制
public static List<FileContent> map(ResultSet rs) throws SQLException, IOException {
    List<FileContent> result = new ArrayList<>();
    while (rs.next()) {
        result.add(mapRow(rs));
    }
    return result;
}

public static void writeToFiles(List<FileContent> list) {
    // Multi-threading handling here, e.g. using CompletableFutures
}
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/108176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档