素数判定アルゴリズムの実行速度比較(Java)
BohYoh.com【著書】明解Javaによるアルゴリズムとデータ構造の2章の素数列挙プログラムを少しだけ書き換え、実行速度を計ってみた。
全部で3通り。ソースコードは以下の通り。
//PrimeNumber1.java // 100,000以下の素数を列挙(1) class PrimeNumber1 { public static void main(String[] args) { long start = System.currentTimeMillis(); int counter = 0; // 除算の回数 for (int n = 2; n <= 100000; n++) { int i; for (i = 2; i < n; i++) { counter++; if (n % i == 0) // 割り切れると素数ではない break; // それ以上の繰返しは不要 } if (n == i) // 最後まで割り切れなかった System.out.println(n); } System.out.println("除算を行った回数:" + counter); long stop = System.currentTimeMillis(); System.out.println("実行にかかった時間は " + (stop - start) + " ミリ秒です。"); } }
//PrimeNumber2.java // 100,000以下の素数を列挙(2) class PrimeNumber2 { public static void main(String[] args) { long start = System.currentTimeMillis(); int counter = 0; // 除算の回数 int ptr = 0; // 得られた素数の個数 int[] prime = new int[500000]; // 素数を格納する配列 prime[ptr++] = 2; // 2は素数である prime[ptr++] = 3; // 3は素数である for (int n = 5; n <= 100000; n += 2) { // 対象は奇数のみ int i; for (i = 1; i < ptr; i++) { // 既に得られた素数で割ってみる counter++; if (n % prime[i] == 0) // 割り切れると素数ではない break; // それ以上の繰返しは不要 } if (ptr == i) // 最後まで割り切れなかったら prime[ptr++] = n; // 素数として配列に登録 } for (int i = 0; i < ptr; i++) // 求めたptr個の素数を表示 System.out.println(prime[i]); System.out.println("除算を行った回数:" + counter); long stop = System.currentTimeMillis(); System.out.println("実行にかかった時間は " + (stop - start) + " ミリ秒です。"); } }
//PrimeNumber3.java // 100,000以下の素数を列挙(3) class PrimeNumber3 { public static void main(String[] args) { long start = System.currentTimeMillis(); int counter = 0; //乗除算の回数 int ptr = 0; //得られた素数の数 int[] prime = new int[500000]; //素数を格納する配列 prime[ptr++] = 2; //素数2を登録 prime[ptr++] = 3; //素数3を登録 for (int n = 5; n <= 100000; n += 2) { //対象は奇数のみ boolean wflag = false; //割り切れたかどうか for (int i = 1; prime[i] * prime[i] <= n; i++) { // 対象の数の平方根以下の全ての素数で除算する counter +=2; if (0 == n % prime[i]) { //割り切れたら素数ではない wflag = true; break; } } if (!wflag) { //最後まで割り切れなかったら prime[ptr++] = n; //素数として新たに登録 counter++; //最後にループに入らなかった分 } } for (int i = 0; i < ptr; i++) //求めたptr個の素数を表示 System.out.println(prime[i]); System.out.println("除算を行った回数: " + counter); long stop = System.currentTimeMillis(); System.out.println("実行にかかった時間は " + (stop - start) + " ミリ秒です。"); } }
(1)
PrimeNumber1.java
除算を行った回数:455189150
実行にかかった時間は 156.969 秒です。
(2)
PrimeNumber2.java
除算を行った回数:46214479
実行にかかった時間は 2.977 秒です。
(3)
PrimeNumber3.java
除算を行った回数: 1298468
実行にかかった時間は 0.517 秒です。
格段に差がでます!(2)までは直感的に思いついたのですが、(3)はソースを見てなるほど〜と思いました。
明解Javaによるアルゴリズムとデータ構造
posted with amazlet at 09.09.12