这是否意味着javamath.floor速度非常慢?

这是否意味着javamath.floor速度非常慢?,java,performance,profiling,floor,Java,Performance,Profiling,Floor,我不太喜欢Java 我正在写一些优化的数学代码,我被我的分析器结果震惊了。我的代码收集值,交错数据,然后根据数据选择值。java运行速度比C++和MATLAB实现慢。p> 我使用的是javac1.7.0\u05 我使用的是Sun/OracleJDK1.7.05 代码中存在执行相关任务的楼层功能。 有人知道解决这个问题的范例吗 我注意到我的floor()函数是用名为StrictMath的东西定义的。Java有类似于-ffast math的东西吗?我希望一定有一种方法可以将楼层函数更改为计算上更合

我不太喜欢Java

我正在写一些优化的数学代码,我被我的分析器结果震惊了。我的代码收集值,交错数据,然后根据数据选择值。java运行速度比C++和MATLAB实现慢。p> 我使用的是
javac1.7.0\u05
我使用的是Sun/OracleJDK1.7.05

代码中存在执行相关任务的楼层功能。

  • 有人知道解决这个问题的范例吗
  • 我注意到我的
    floor()
    函数是用名为
    StrictMath
    的东西定义的。Java有类似于
    -ffast math
    的东西吗?我希望一定有一种方法可以将楼层函数更改为计算上更合理的函数,而无需编写我自己的函数

    public static double floor(double a) {
        return StrictMath.floor(a); // default impl. delegates to StrictMath
    }
    
  • 编辑

    所以有几个人建议我试着做一个演员。我试过了,但在walltime中完全没有变化

    private static int flur(float dF)
    {
        return (int) dF;
    }
    
    413742铸造地板功能

    394675数学楼


    这些测试是在没有分析器的情况下运行的。曾尝试使用探查器,但运行时发生了巨大变化(15分钟以上,因此我退出)。

    首先:探查器显示,您将99%的cpu时间花在地板功能上。这并不表示地面速度慢。如果你除了地板什么都不做那是完全正常的。然而,由于其他语言似乎更有效地实现了floor,所以您的假设可能是正确的

    我从学校就知道,一个简单的floor实现(只对正数有效,对负数无效)可以通过转换为整数/长来完成。这是语言不可知论,是CS课程中的一些常识

    这里有一些微型长椅。在我的机器上工作,支持我在学校学到的东西;)

    #
    公共类演员/地板{
    私有静态最终整数轮=10000000;
    公共静态void main(字符串[]args)
    {
    double[]VAL=新的双[轮];
    double[]res=新的双[轮];
    //令人敬畏的测试数据
    对于(int i=0;i

    }

    您可能想尝试一下

    这是一篇关于这个问题的帖子。关于为什么默认的数学库很慢,有一些很好的提示。他们正在讨论除
    楼层
    以外的其他操作,但我想他们的发现可以概括。我觉得很有趣

    编辑

    据介绍,floor在7(b79)、6u21(b01)中实现了一个纯java代码,从而获得了更好的性能。中的楼层代码仍然比中的楼层代码长一点,但可能不会对这样的性能负责。堕落您使用的是什么JDK?你能试试更新的版本吗

    Math.floor()
    在我的机器上速度惊人,在一个紧密的循环中,每次调用大约7纳秒。(Windows7、Eclipse、OracleJDK7)。我希望它在几乎所有情况下都会非常快,如果它成为瓶颈,我会非常惊讶

    一些想法:

    • 我建议在不运行分析器的情况下重新运行一些基准测试。有时,分析器在插入二进制文件时会产生虚假的开销,特别是对于像
      Math.floor()
      这样可能是内联的小函数
    • 尝试几个不同的JVM,您可能遇到了一个模糊的bug
    • 在优秀的Apache库中尝试
      FastMath
      类,该库包含一个新的floor实现。如果速度更快,我会很惊讶,但你永远不知道
    • 检查您没有运行任何可能干扰Java调用本机代码能力的虚拟化技术或类似技术(在一些
      Java.lang.Math
      函数中使用,包括
      Math.floor()

    下面是一个关于你假设代码99%的时间都花在
    地板上的合理性检查。让我们假设您的java和C++版本的算法在输出的结果上都是正确的。为了论证,让我们假设两个版本调用等效的
    floor
    函数的次数相同。所以时间函数是

    t(input) = nosFloorCalls(input) * floorTime + otherTime(input)
    
    其中
    floorTime
    是在平台上呼叫
    floor
    所用的时间

    现在假设假设正确,并且 FooLime< /C> >在java上要花费很多(在大约花费99%的执行时间),那么你会期望java应用程序运行的C++(50倍或更多)比C++版本慢。如果你没有看到这一点,那么你的假设很可能是错误的


    如果这个假设是错误的,这里有两种不同的解释

  • 这是一个测量异常;i、 探查器不知怎么弄错了。尝试使用不同的探查器

  • <> L> > p>代码中的java版本中有一个bug,导致它调用<代码> Load 比代码的C++版本多很多倍。


    值得注意的是,监视一个方法需要一些开销,对于VisualVM来说,这是相当高的。如果您有一个经常调用但很少执行的方法,那么它可能会占用大量CPU。e、 我见过整数
    public class Cast/Floor {
    
        private static final int ROUNDS = 10000000;
    
        public static void main(String[] args)
        {
            double[] vals = new double[ROUNDS];
            double[] res = new double[ROUNDS];
    
            // awesome testdata
            for(int i = 0; i < ROUNDS; i++)
            {
                vals[i] = Math.random() * 10.0;
            }
    
            // warmup
            for(int i = 0; i < ROUNDS; i++)
            {
                res[i] = floor(vals[i]);
            }
    
            long start = System.currentTimeMillis();
            for(int i = 0; i < ROUNDS; i++)
            {
                res[i] = floor(vals[i]);
            }
            System.out.println(ROUNDS + " Rounds of Casts took " + (System.currentTimeMillis() - start) +" ms");
        }
    
        private static double floor(double arg)
        {
            // Floor.java
            return Math.floor(arg);
            // or Cast.java
            return (int)arg;
        }
    
    t(input) = nosFloorCalls(input) * floorTime + otherTime(input)
    
    // Rounds to zero, instead of Negative infinity.
    public static double floor(double a) {
        return (long) a;
    }
    
    public static void main(String... args) {
        int size = 100000;
        double[] a = new double[size];
        double[] b = new double[size];
        double[] c = new double[size];
        for (int i = 0; i < a.length; i++) a[i] = Math.random()  * 1e6;
    
        for (int i = 0; i < 5; i++) {
            timeCast(a, b);
            timeFloor(a, c);
            for (int j = 0; j < size; j++)
                if (b[i] != c[i])
                    System.err.println(a[i] + ": " + b[i] + " " + c[i]);
        }
    }
    
    public static double floor(double a) {
        return a < 0 ? -(long) -a : (long) a;
    }
    
    private static void timeCast(double[] from, double[] to) {
        long start = System.nanoTime();
        for (int i = 0; i < from.length; i++)
            to[i] = floor(from[i]);
        long time = System.nanoTime() - start;
        System.out.printf("Cast took an average of %.1f ns%n", (double) time / from.length);
    }
    
    private static void timeFloor(double[] from, double[] to) {
        long start = System.nanoTime();
        for (int i = 0; i < from.length; i++)
            to[i] = Math.floor(from[i]);
        long time = System.nanoTime() - start;
        System.out.printf("Math.floor took an average of %.1f ns%n", (double) time / from.length);
    }
    
    Cast took an average of 62.1 ns
    Math.floor took an average of 123.6 ns
    Cast took an average of 61.9 ns
    Math.floor took an average of 6.3 ns
    Cast took an average of 47.2 ns
    Math.floor took an average of 6.5 ns
    Cast took an average of 2.3 ns
    Math.floor took an average of 5.6 ns
    Cast took an average of 2.3 ns
    Math.floor took an average of 5.6 ns
    
    public static final int floor(final float value) {
        return ((int) value) - (Float.floatToRawIntBits(value) >>> 31);
    }