1

让我们考虑一下这种情况:我正在读取一个文件,然后稍微调整每一行,然后将数据存储在一个新文件中。现在,我尝试了两种方法来做到这一点:

  1. 将数据存储在字符串中,然后在最后将其写入目标文件,如下所示:

            InputStream ips = new FileInputStream(file);
            InputStreamReader ipsr = new InputStreamReader(ips);
            BufferedReader br = new BufferedReader(ipsr);
    
            PrintWriter desFile = new PrintWriter(targetFilePath);
            String data = "";
            while ((line = br.readLine()) != null) {
                if (line.contains("_Stop_"))
                    continue;
                String[] s = line.split(";");
                String newLine = s[2];
                for (int i = 3; i < s.length; i++) {
                    newLine += "," + s[i];
                }
                data+=newLine+"\n";
            }
            desFile.write(data);
            desFile.close();
            br.close();
    
  2. 在 while 循环中直接使用 PrintWriter 的 println() 方法,如下所示:

             while ((line = br.readLine()) != null) {
                if (line.contains("_Stop_"))
                    continue;
                String[] s = line.split(";");
                String newLine = s[2];
                for (int i = 3; i < s.length; i++) {
                    newLine += "," + s[i];
                }
                desFile.println(newLine);
            }
            desFile.close();
            br.close();
    

第二个过程比第一个快得多。现在,我的问题是,在这两个过程中发生了什么如此不同,以至于执行时间差异如此之大?

4

3 回答 3

2

附加到您的字符串将:

  1. 为新字符串分配内存
  2. 复制之前复制的所有数据。
  3. 从新字符串中复制数据。

您对每一行重复此过程,这意味着对于 N 行输出,您复制 O(N^2) 个字节。

同时,写入您的 PrintWriter 将:

  1. 将数据复制到缓冲区。
  2. 偶尔刷新缓冲区。

这意味着对于 N 行输出,您只复制 O(N) 个字节。

于 2014-10-24T22:52:35.797 回答
1

一方面,您通过使用 += 附加来创建大量新的 String 对象。我认为这肯定会减慢速度。

尝试使用在循环外声明的 StringBuilder sb 进行附加,然后调用 desFile.write(sb.toString()); 看看效果如何。

于 2014-10-24T22:49:06.623 回答
1

首先,这两个进程不会产生相同的数据,因为调用的进程println在行之间会有行分隔符,而将所有数据构建在缓冲区中并一次全部写入的进程不会。

但性能差异的原因可能是您生成和丢弃的对象数量巨大StringStringBuilder需要分配内存以将完整文件内容保存在内存中,以及垃圾收集器所花费的时间。

如果您要进行大量的字符串连接,尤其是在循环中,最好StringBuilder在循环之前创建一个并使用它来累积循环中的结果。

但是,如果您要处理大文件,最好边写输出。您的应用程序的内存要求会更低,而如果您在内存中构建整个结果,则所需的内存将等于输出文件的大小。

于 2014-10-24T22:50:08.727 回答