[英]which of the two is a better way of creating and destroying objects?
我對第26和27行有疑問:
String dumb = input.nextLine();
output.println(dumb.replaceAll(REMOVE, ADD));
我希望我能夠將其縮小到一行並能夠節省空間,所以我做到了:
output.println(new String(input.nextLine()).replaceAll(REMOVE, ADD));
但是現在我想知道性能。 我知道該程序是基礎安靜的程序,不需要優化,但是我想學習。
我的觀察方式是,在第一種情況下,我正在創建一個愚蠢的字符串對象,但是一旦退出循環,該對象將被放棄,JVM應該對其進行清理,對嗎? 但是JVM是否比程序執行循環更快地清除了廢棄的對象? 還是在程序完成后會有幾個字符串對象在等待垃圾回收?
我的邏輯是正確的嗎?在第二種情況下,String對象是在運行中立即創建並在程序通過該行時銷毀的? 這實際上是性能提升嗎?
如果您能為我解決這個問題,我將不勝感激。
謝謝,
ps,如果您想知道該程序(我假設它很簡單),它將輸入文件和輸出文件,然后將兩個詞(程序接收輸入文件,將第一個詞替換為第二個詞並將其寫入)第二個文件。 如果您實際上已經讀了那么多書,並且想提出一些方法來改善我的代碼,請這樣做。 我將非常感謝。
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();
}
}
我要說的第一件事是:
不必擔心過早地優化性能。 Java編譯器很聰明,它將為您優化很多這些東西,即使您沒有優化,也會花費很少的時間。 您所要到達的流IO的運行時間已經比您要談論的時間長幾個數量級。
最重要的是代碼易於理解。 從示例開始,您已經擁有了不錯的代碼樣式,因此請繼續進行下去。 除您之外 , 其他人更容易閱讀這兩個代碼片段中的哪一個? 那是最好的選擇。 :)
也就是說,這是您問題的一些更具體的答案:
垃圾回收絕對會拾取在循環范圍內實例化的對象。 它在循環內實例化的事實意味着,一旦Java超出范圍,Java便會對其進行標記以進行清理。 下次GC運行時,它將清除所有標記為需要清除的內容。
內聯創建對象仍然會創建一個對象。 構造函數仍被調用,內存仍被分配...在幕后,它們確實非常相似。 只是在一種情況下該對象具有名稱,而在另一種情況下則沒有。 您不會通過將兩行代碼合並為一個來節省任何實際資源。
“ input.nextLine()”已經返回一個字符串,因此您無需將其包裝在新的String()中。 (因此,確實刪除該對象將導致實例化一個更少的對象!)
一旦本地對象超出范圍,便可以使用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();
}
}
}
如果您擔心對象的創建和性能,請使用探查器來確保您的代碼。 並且請記住,因為input.nextLine()
返回String的一個不變實例,所以new String(input.nextLine())
是完全沒有意義的。 因此只需執行output.println(input.nextLine().replaceAll(REMOVE, ADD));
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.