我对第26行和第26行有疑问。 27:
String dumb = input.nextLine();
output.println(dumb.replaceAll(REMOVE, ADD));
我希望我能够将它缩小到单行,并且能够节省空间,所以我做了:
output.println(new String(input.nextLine()).replaceAll(REMOVE, ADD));
但现在我对性能感到疑惑。我知道这个程序基本安静,不需要优化,但我想学习这个 我看待它的方式,在第一个场景中,我正在创建一个字符串对象哑,但是一旦我离开循环,对象就会被抛弃,JVM应该清理它,对吧?但是JVM是否比程序通过循环更快地清理被抛弃的对象?或者,一旦程序完成,会有几个字符串对象等待垃圾收集吗?
并且我的逻辑是正确的,在第二种情况下,String对象是动态创建的,并在程序通过该行后被销毁?这实际上是性能提升吗?
如果你能为我解决这个问题,我会很感激。谢谢,
P.S。如果你想知道程序(我认为它是直接的)它接收一个输入文件,输出文件和两个单词,程序获取输入文件,用第二个单词替换第一个单词并将其写入第二个档案。如果你真的已经阅读了这篇文章,并希望建议我可以使我的代码更好的方法,请这样做。我会非常感激的。
import java.io.File;
import java.util.Scanner;
import java.io.PrintWriter;
public class RW {
public static void main(String[] args) throws Exception{
String INPUT_FILE = args[0];
String OUTPUT_FILE = args[1];
String REMOVE = args[2];
String ADD = args[3];
File ifile = new File(INPUT_FILE);
File ofile = new File(OUTPUT_FILE);
if (ifile.exists() == false) {
System.out.println("the input file does not exists in the current folder");
System.out.println("please provide the input file");
System.exit(0);
}
Scanner input = new Scanner(ifile);
PrintWriter output = new PrintWriter(ofile);
while(input.hasNextLine()) {
String dumb = input.nextLine();
output.println(dumb.replaceAll(REMOVE, ADD));
}
input.close();
output.close();
}
}
答案 0 :(得分:3)
我要说的第一件事就是:
不要担心过早地优化性能。 Java编译器很聪明,它会为你优化很多这样的东西,即使它没有你优化非常小的时间。您已经到达的流IO已经运行了比您正在谈论的时间长几个数量级。
最重要重要的是代码易于理解。你有一个很好的代码风格,从你的例子开始,所以保持这个。对于以外的其他人来说,哪两个代码段更容易阅读? 那是最好的选择。 :)
尽管如此,这里有一些更具体的问题答案:
垃圾收集绝对会获取在循环范围内实例化的对象。它在循环中实例化的事实意味着Java一旦超出范围就已经标记了它以进行清理。 GC下次运行时,它将清理所有标记为清理的东西。
创建对象内联仍将创建一个对象。构造函数仍然被调用,内存仍然被分配......在引擎盖下,它们真的非常相似。只是在一种情况下,对象具有名称,而在另一种情况下,它不具有名称。您不会通过将两行代码合并为一行来保存任何实际资源。
“input.nextLine()”已经返回一个String,因此您不需要将其包装在新的String()中。 (所以是的,删除实际将导致实例化少一个对象!)
答案 1 :(得分:1)
本地对象一旦超出范围,就有资格使用GC。这并不意味着GC会在那个时刻清理它们。符合条件的对象经历了生命周期。 GC可能会也可能不会立即收集它们。
就你的程序而言,除了一两行之外没有什么可以优化的。以下是重组程序。
import java.io.File;
import java.util.Scanner;
import java.io.PrintWriter;
public class Test {
public static void main(String[] args) throws Exception {
String INPUT_FILE = args[0];
String OUTPUT_FILE = args[1];
String REMOVE = args[2];
String ADD = args[3];
File ifile = new File(INPUT_FILE);
File ofile = new File(OUTPUT_FILE);
if (ifile.exists() == false) {
System.out.println("the input file does not exists in the current folder\nplease provide the input file");
System.exit(0);
}
Scanner input = null;
PrintWriter output = null;
try {
input = new Scanner(ifile);
output = new PrintWriter(ofile);
while (input.hasNextLine()) {
output.println(input.nextLine().replaceAll(REMOVE, ADD));
}
} finally {
if (input != null)
input.close();
if(output != null)
output.close();
}
}
}
答案 2 :(得分:1)
如果您担心obejct创建和性能,请使用分析器来确定您的代码。请记住,执行new String(input.nextLine())
完全没有意义,因为input.nextLine()
返回String的不可变实例。所以只需output.println(input.nextLine().replaceAll(REMOVE, ADD));
。