让我们考虑这种情况:我正在读取一个文件,然后稍微调整每一行,然后将数据存储在一个新文件中。现在,我尝试了两种方法:
将数据存储在String中,然后将其写入目标文件,如下所示:
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();
在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();
第二个过程比第一个过程快。现在,我的问题是在这两个过程中发生的情况如此不同,执行时间差异如此之大?
答案 0 :(得分:2)
追加到您的字符串:
您对每一行重复此过程,这意味着对于N行输出,您将复制O(N ^ 2)个字节。
同时,写信给你的PrintWriter:
意味着对于N行输出,只复制O(N)个字节。
答案 1 :(得分:1)
首先,你通过使用+ =附加来创建大量新的String对象。我认为这肯定会让事情变得缓慢。
尝试使用在循环外部声明的StringBuilder sb追加,然后调用desFile.write(sb.toString());并了解其表现如何。
答案 2 :(得分:1)
首先,这两个进程不会生成相同的数据,因为调用println
的数据将在行之间包含行分隔符,而在缓冲区中构建所有数据的行并且不会立刻写下来。
但是性能差异的原因可能是您生成和丢弃的String
和StringBuilder
对象的大量数量,需要分配的内存来保存内存中的完整文件内容,以及垃圾收集器所花费的时间。
如果您要进行大量的字符串连接,尤其是在循环中,最好在循环之前创建StringBuilder
并使用它在循环中累积结果。
但是,如果您要处理大型文件,最好随时编写输出。应用程序的内存要求会降低,而如果在内存中构建整个结果,则所需的内存将等于输出文件的大小。