2

私のクラスでは、非常に大きな数までの任意の数の素因数分解を計算する「因数分解」アプリケーションを作成する問題が割り当てられました。彼はNumber.java、その数が素数かどうかを計算するクラスを私たちに与えてくれました。

// Number.java
public class Number {  
    long n;
    public Number(long number) {
        n = number;
    }
    boolean isPrime() {
        for(long k = 2; k < n; k++) {
          if(n % k == 0) return false;
        }
        return true;
    }
}

これに関する唯一の問題は、Number.javaクラスにコンストラクターがあることです。これにより、この状況では「モバイル」が少なくなります。つまり、引数の素因数を計算するループで、新しい Number オブジェクトが何度も作成されているということです。ループの繰り返しごとにprivate Number isPrimeFactor = new Number()新しい a を作成するよりも、上部にa を定義する方が理にかなっているのではないでしょうか? Number isPrimeFactor = new Number(i)このことを先生に尋ねたのですが、あまり答えてくれません。これが私が話していることのいくつかのサンプルコードです。

while (remainder!=0 && j<n) {
        Number isFactor = new Number(j);
        if(isFactor.isPrime() && remainder%j==0) {
            remainder = remainder / j;
            factor[i]=j;
            temp = (int) j;
            multiplicity[temp] = multiplicity[temp]+1;
            i++;
        } else {
            j++;
        }
    }
4

6 に答える 6

2

はい、newかなりコストがかかります。つまり、数千回の呼び出しは、 のインスタンスを 1 つだけ持ち、関連する値をたとえば a で変更するisPrimeFactor = new Number(j)よりも効率が悪いことを意味します。これは、新しいメモリが割り当てられ、インスタンスにアクセスできなくなると、そのメモリがガベージ コレクターによって時々解放されるためです。NumbernisPrimeFactor.setN(j)new

ただし、 Number を不変にする利点は、コードの一部で値が変更され、別のコードでは変更されていないと見なされるリスクがないことです (たとえば、スレッドを使用している場合は非常に優れたプロパティです)。

ところで、Numberあなたの教授によって与えられたクラスは、ミュータブルであろうとなかろうと、ひどい OO 設計だと思います。

于 2013-03-14T15:31:33.020 に答える
1

ここで意味があるのは、 に渡すことだけを目的としたコンストラクターを持たないことです: それが関数の引数の目的です!nisPrime()

public class PrimeChecker {     
  public static boolean isPrime(long n) {
    for(long k = 2; k * k < n; k++) {
      if(n % k == 0) return false;
    }
    return true;
  }
}
于 2013-03-14T15:33:18.537 に答える
0

他の最適化はさておき、これらのために数値、整数などを作成する理由はありません。これで上記のすべてをスキップできます:

public static boolean isPrime(long number) {
    for(long k = 2; k < n; k++) {
      if(n % k == 0) return false;
    }
    return true;
}
于 2013-03-14T15:32:48.983 に答える
0

数値を一度だけインスタンス化し、そのフィールドを繰り返し割り当てる方が間違いなく高速です。ただし、この場合はテストisPrimeがボトルネックになっている可能性が高いため、違いはほとんどわかりません。

于 2013-03-14T15:33:06.160 に答える
0

メモリ/速度/コードの読みやすさ/メンテナンスのいずれかを常に選択できます。したがって、客観的な方法で質問に答えることができません。

このソリューションは非効率的ですか? たぶん、しかし繰り返しますが、関数呼び出しは高価なので、関数呼び出しを含むソリューションは非効率的であるとラベル付けされる可能性があります.

これが宿題や学習課題である場合、コードの効率はそれほど重要ではありませんが、関連する概念を説明する明確なコードを作成することは非常に重要です!

Ps。

素数をチェックする私が見たほとんどのコードには、数値/整数をパ​​ラメーターとして受け取るメソッド「isPrime」があります。

于 2013-03-14T15:29:41.943 に答える
-2

おっしゃるとおり、ループ内でのオブジェクトの割り当てはパフォーマンスのアンチパターンです。代わりに、静的クラス メンバーを使用することで、実行速度を上げ、メモリ使用量を改善できます。

// Number.java
public class Number {  
  private static long n;
 public static void setNumber(long number){
        n = number;
 }
 static boolean isPrime() {
     for(long k = 2; k < n; k++) {
       if(n % k == 0) return false;
     }
     return true;
 }
}
于 2013-03-14T15:29:43.760 に答える