質問
私はこのコード:
package math;
import java.io.IOException;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) throws IOException
{
System.out.println("Hi, I will beat Java's Math.sqrt(double) method");
System.out.println("Both ways of calculation will be done");
System.out.println("I will time how long they took to calculate");
System.out.println("Random doubles will be generated");
System.out.println();
System.out.println("Please give the number of sqrt-calculation will be done");
int calcs = new Scanner(System.in).nextInt();
boolean output = true;
if (calcs > 10000)
{
System.out.println("You're asking much calculations");
System.out.println("Disabling output is recommend");
System.out.println("Disable output? (y/n)");
char a = (char) System.in.read();
if (a == 'y')
{
output = false;
}
}
System.out.println("Press enter to start");
System.in.read();
test(calcs, output);
System.out.println();
System.out.println("I was much faster I think");
System.out.println("Now you can check my precision");
System.out.println("Please give a complex double");
double x = Double.parseDouble(new Scanner(System.in).next());
System.out.println();
System.out.println("Math.sqrt(" + x + ") = " + Math.sqrt(x));
System.out.println("SqrtCalculator.sqrt(" + x + ") = " + sqrt(x));
System.out.println("------------------------");
System.out.println("Now please make your conclusion");
System.out.println("Thanks for trying");
}
public static void test(int calculations, boolean output)
{
double factor = Math.random() / 2;
// Math
long mathStart = System.currentTimeMillis();
for (int i = 1; i <= calculations; i++)
{
double x = i * factor;
double result = Math.sqrt(x);
if (output)
{
System.out.println("Math.sqrt(" + x + ") = " + result);
}
}
long mathStop = System.currentTimeMillis();
long mathTime = mathStop - mathStart;
// My Method
long myStart = System.currentTimeMillis();
for (int i = 1; i <= calculations; i++)
{
double x = i * factor;
double result = sqrt(x);
if (output)
{
System.out.println("SqrtCalculater.sqrt(" + x + ") = " + result);
}
}
long myStop = System.currentTimeMillis();
long myTime = myStop - myStart;
System.out.println();
if (output)
System.out.println("---------------------------");
System.out.println("Here are the results:");
System.out.println("Math and SqrtCalculator did each " + calculations + " of the same sqrt-calculations");
System.out.println();
System.out.println("Math: " + mathTime + " milliseconds");
System.out.println("I: " + myTime + " milliseconds");
}
public final static double sqrt(double x)
{
double previous = 1;
double now = 0;
for (;;)
{
now = (x / previous + previous) / 2;
if (previous == now)
{
return now;
}
previous = now;
}
}
}
このsqrt方法を"heroon".
ばんは私のプログラムお願い80000計算し無効で、出力、数学なども関わっています。sqrt()であっ方法です。ま80000calcsい出力が、私の方法のほうが格段に速くできます。
できる人に説明す。
感謝
申し訳ない。
解決
私はあなたの結果を再現することができませんでした。 EclipseのガリレオとJDK 1.6.0を使用して、いくつかの回を試してみました。
80000の場合、出力は無効になって、私のような何かを得ました
Math: 15 milliseconds
I: 32 milliseconds
小さな回は、それがより良い利用System.nanoTime()
以上の相互作用になります。
80000の場合は、出力が有効になってます:
Math: 3609 milliseconds
I: 4906 milliseconds
だから、おそらく問題は、出力を処理する方法はある(スクロール、バッファリング、...)
他のヒント
Math.sqrt方法延期します。 (JDKのソースを見て - あなたはそれがネイティブメソッドだということがわかります。)これは、あなたが書くだろう何よりも確かに高速です。それも、あなたがコード化されたのと同じアルゴリズムを使用している場合があります。これはよく知られています。あなたの方法は、単純に平方根を計算するためのニュートン法です。バビロンのため、それは、知られています。ニュートンは、単純に計算を使用してそれをrederived。二次収束が良いです。
あなたがやったものは何でも、それはあなたが何が新しいか注目すべき発見したとは考えにくいです。 IOでやってた何かのように聞こえるが、人為的な結果にバイアスされます。
あなたはおそらく出力時間と実際の計算時間を圧倒し、バッファリングのまぐれに実行しています。プロファイラは実際に時間を消費しているものをお見せします。
既存の実装を改善しようとしているために賞賛。あなたが失敗した場合でも、あなたはプロセスにおけるアルゴリズムについて多くを学ぶことができます。当然、あなたはマイクロベンチマークのこの種を使用して、あなたの代わりをテストする必要があります。残念ながら、数多くの落とし穴があります。具体的には、はは、あなたの計算で、無関係なコード、例えばテストと出力を混在させないでください。 のの初期のテストでJVMを温めるん。 にベンチマーキングでこの記事によりあります。浮動小数点値を比較するときにも、浮動小数点数を比較するために、これらのガイドラインを検討。