Java:性能SQRT计算
我有以下代码:Java:性能SQRT计算,java,performance,math,sqrt,Java,Performance,Math,Sqrt,我有以下代码: 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");
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;
}
}
}
package数学;
导入java.io.IOException;
导入java.util.Scanner;
公共班机
{
公共静态void main(字符串[]args)引发IOException
{
println(“嗨,我将击败Java的Math.sqrt(double)方法”);
System.out.println(“两种计算方式都将进行”);
println(“我会计算他们花了多长时间”);
System.out.println(“将生成随机双精度”);
System.out.println();
System.out.println(“请给出将要进行的sqrt计算的数量”);
int calcs=新扫描仪(System.in).nextInt();
布尔输出=真;
如果(计算值>10000)
{
System.out.println(“你要求的计算太多了”);
System.out.println(“建议禁用输出”);
System.out.println(“禁用输出”(y/n)”;
char a=(char)System.in.read();
如果(a='y')
{
输出=假;
}
}
System.out.println(“按回车键开始”);
System.in.read();
测试(计算、输出);
System.out.println();
System.out.println(“我觉得我快多了”);
System.out.println(“现在您可以检查我的精度”);
System.out.println(“请给出一个复杂的双精度”);
double x=double.parseDouble(新扫描仪(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(“现在请做出结论”);
System.out.println(“感谢您的尝试”);
}
公共静态无效测试(整数计算、布尔输出)
{
双因子=Math.random()/2;
//数学
long mathStart=System.currentTimeMillis();
对于(int i=1;i您可能用输出时间压倒了实际的计算时间,并且遇到了缓冲的侥幸。探查器将向您显示实际消耗时间的内容。Math.sqrt方法遵从StrictMath.sqrt,这是在硬件或本机代码中完成的。(查看JDK的源代码—您将看到它是一个本机方法。)这肯定比你要写的任何东西都要快。它甚至可能使用与你编写的算法相同的算法。这是众所周知的。你的方法只是牛顿计算平方根的方法。这是众所周知的;牛顿只是用微积分重新驱动它。二次收敛很好
无论你做了什么,你都不可能发现任何新的或值得注意的东西。听起来似乎与IO有关的事情是人为地使结果产生偏差。努力改进现有实现的功劳;即使你失败了,你也可以在这个过程中学到很多关于算法的知识。当然,你必须测试你的备选方案使用这种微基准。不幸的是,存在很多缺陷。尤其是,不要把无关的代码(例如测试和输出)与计算结合起来;在测试早期对JVM进行预热。还有更多。在比较浮点值时,考虑这些。 < P>我不能复制您的结果。尝试了一些T。imes使用EclipseGalileo和JDK1.6.0
对于80000,输出被禁用,我得到如下结果:
Math: 15 milliseconds
I: 32 milliseconds
小时候,最好使用System.nanoTime()
或更多交互
对于80000,已启用输出:
Math: 3609 milliseconds
I: 4906 milliseconds
因此,问题可能在于处理输出的方式(滚动、缓冲等)请注意,通常情况下,您会使用从输入的指数派生的更好的起始值。这在实践中非常有用,例如,如果您想计算大整数的近似平方根。您的eclipse控制台设置是什么?无固定宽度,限制:1000000,制表符:8,按标准显示,按标准显示错误,颜色:{应该没有影响}。