0

26 行目と 27 行目に質問があります。

String dumb = input.nextLine();
output.println(dumb.replaceAll(REMOVE, ADD));

これを1行に縮小してスペースを節約できることを望んでいたので、次のようにしました。

output.println(new String(input.nextLine()).replaceAll(REMOVE, ADD));

しかし今、私はパフォーマンスについて疑問に思っています。このプログラムが静かな基本であり、最適化が必要ないことは理解していますが、これを学びたいです。
私の見方では、最初のシナリオでは、文字列オブジェクトのダムを作成していますが、ループを離れると、オブジェクトは破棄され、JVM はそれをクリーンアップする必要がありますよね? しかし、JVM は、プログラムがループを通過するよりも速く、放棄されたオブジェクトをクリーンアップしますか? または、プログラムが完了すると、ガベージ コレクションを待機しているいくつかの文字列オブジェクトが存在しますか?

2番目のシナリオでは、プログラムがその行を通過すると、Stringオブジェクトがオンザフライで作成され、破棄されるという私の論理は正しいですか? これは実際にパフォーマンスの向上ですか?

これを解決していただければ幸いです。

ありがとうございました、

psプログラムについて疑問に思っている場合(私はそれが簡単だと思いました)、入力ファイルと出力ファイル、および2つの単語を受け取ります。プログラムは入力ファイルを受け取り、最初の単語を2番目の単語に置き換えて書き込みます2 番目のファイル。実際にここまで読んで、コードを改善する方法を提案したい場合は、そうしてください。とても感謝しています。

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();


    }
}
4

3 に答える 3

3

私が最初に言おうとしているのは、次のことです。

時期尚早にパフォーマンスを最適化することについて心配する必要はありません。Java コンパイラはスマートで、このようなことの多くを最適化してくれます。最適化していなくても、信じられないほどわずかな時間を最適化しています。あなたがそこに行っているストリーム IO は、あなたが話している時間よりも桁違いに長く実行されています。

最も重要なことは、コードがいかに理解しやすいかということです。あなたの例から、素敵なコードスタイルを手に入れたので、それを維持してください。2 つのコード スニペットのうち、あなた以外の人が読みやすいのはどれですか? それが最良の選択肢です。:)

とはいえ、あなたの質問に対するより具体的な回答は次のとおりです。

  1. ガベージ コレクションは、ループのスコープ内でインスタンス化されたオブジェクトを完全にピックアップします。ループ内でインスタンス化されているという事実は、Java が範囲外になるとすぐにクリーンアップするようにマークしていることを意味します。次回 GC が実行されると、クリーンアップの対象としてマークされたものはすべてクリーンアップされます。

  2. オブジェクトをインラインで作成しても、オブジェクトは作成されます。コンストラクターはまだ呼び出され、メモリはまだ割り当てられています...内部的には、それらは本当に非常に似ています。オブジェクトに名前がある場合とない場合があるだけです。2 行のコードを 1 行にまとめても、実際のリソースを節約することはできません。

  3. 「input.nextLine()」はすでに String を返しているため、新しい String() でラップする必要はありません。(つまり、実際にそれを削除すると、インスタンス化されるオブジェクトが 1 つ少なくなります!)

于 2012-05-16T05:29:31.467 に答える
1

ローカル オブジェクトは、スコープ外になると GC の対象になります。これは、GC がそれらをその瞬間にクリーンアップするという意味ではありません。適格なオブジェクトはライフサイクルを経ています。GC はそれらをすぐに収集する場合と収集しない場合があります。

プログラムに関する限り、最適化する必要があるのは 1 ~ 2 行だけです。以下は、再構築されたプログラムです。

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();
        }
    }
}
于 2012-05-16T05:27:40.830 に答える
1

オブジェクトの作成とパフォーマンスが気になる場合は、プロファイラーを使用してコードを測定してください。また、文字列の不変のインスタンスを返すため、実行してnew String(input.nextLine())もまったく意味がないことに注意してください。input.nextLine()だからただやってくださいoutput.println(input.nextLine().replaceAll(REMOVE, ADD));

于 2012-05-16T05:40:31.727 に答える