簡體   English   中英

這兩種方法中哪一種是創建和銷毀對象的更好方法?

[英]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的運行時間已經比您要談論的時間長幾個數量級。

重要的是代碼易於理解。 從示例開始,您已經擁有了不錯的代碼樣式,因此請繼續進行下去。 除您之外其他人更容易閱讀這兩個代碼片段中的哪一個? 是最好的選擇。 :)

也就是說,這是您問題的一些更具體的答案:

  1. 垃圾回收絕對會拾取在循環范圍內實例化的對象。 它在循環內實例化的事實意味着,一旦Java超出范圍,Java便會對其進行標記以進行清理。 下次GC運行時,它將清除所有標記為需要清除的內容。

  2. 內聯創建對象仍然會創建一個對象。 構造函數仍被調用,內存仍被分配...在幕后,它們確實非常相似。 只是在一種情況下該對象具有名稱,而在另一種情況下則沒有。 您不會通過將兩行代碼合並為一個來節省任何實際資源。

  3. “ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM