我有这样的代码:

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次计算,我禁止输出,Math.sqrt()是远远超过我的方法更快。如果我问80000个Calcs(计算)和启用输出,我的方法要快得多。

有人能解释一下吗?

由于

对不起坏英语。

有帮助吗?

解决方案

我无法重现你的结果。尝试使用Eclipse的伽利略和JDK 1.6.0一些时间。

有关80000,输出禁用,我是这样的:

Math: 15 milliseconds
I:    32 milliseconds

小倍,这将是更好的使用System.nanoTime()或多个交互。

有关80000,输出使能:

Math: 3609 milliseconds
I:    4906 milliseconds

因此可能问题是,输出的处理方式(滚动,缓冲剂,...)

其他提示

在Math.sqrt方法推迟到StrictMath.sqrt,这是在硬件或本机代码来完成。 (查看源代码的JDK - 你会看到,这是一个本地方法。)这当然是快比什么你会写。它甚至可以使用相同的算法,你编码。这是众所周知。你的方法根本牛顿计算平方根法。它被称为 href="http://en.wikipedia.org/wiki/Methods_of_computing_square_roots" rel="noreferrer">;牛顿只是重新推导它使用微积分。二次衔接好。

不管你做了,这是不可能的,你已经发现任何新的或值得关注。喜欢的东西的声音具有IO做的是人为地偏置的结果。

您很可能压倒的实际计算时间与输出时间,并运行至缓冲的侥幸。一个分析器会告诉你什么实际消耗的时间。

对于试图改善在现有的实施奖励;即使你失败了,你可以学到很多在这个过程中的算法。当然,你必须使用这种微基准测试你的选择。不幸的是,有无数的陷阱。尤其是,混合不相干码,e.g测试和输出,用你的计算; 的测试中的早期热身JVM。还有更多关于bechmarking 这文章。此外,比较浮点值时,考虑到这些准则比较浮点数

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top