如何停止JVM跳过循环

如何停止JVM跳过循环,jvm,java-native-interface,trigonometry,jvm-hotspot,Jvm,Java Native Interface,Trigonometry,Jvm Hotspot,我有自己的测试类,应该在不删除任何东西的情况下进行计时。将Java从StrictMath.sin()调用的本机与我自己的本机进行比较的100000000次测试示例: 30度 sineNative():18342858纳秒(#1),1574331纳秒(#10) sinCosTanNew6():13751140纳秒(1),1569848纳秒(10) 60度 sinennative():2520327020纳秒(#1),2520108337纳秒(#10) sinCosTanNew6():1293595

我有自己的测试类,应该在不删除任何东西的情况下进行计时。将Java从StrictMath.sin()调用的本机与我自己的本机进行比较的100000000次测试示例:

30度
sineNative():18342858纳秒(#1),1574331纳秒(#10)
sinCosTanNew6():13751140纳秒(1),1569848纳秒(10)

60度
sinennative():2520327020纳秒(#1),2520108337纳秒(#10)
sinCosTanNew6():12935959纳秒(1),1565365纳秒(10)

从30到60本机时间飞涨*137,而我的是~常数。此外,即使repsDone返回==reps,某些时间也不可能太低。我希望他们应该是>1*次

CPU:G3258@4GHz
操作系统:Windows 7 HB SP1
构建路径:jre1.8.0_211
雷普雷克斯:


我尝试在循环中添加angle+,这会将时间乘以一个更合理的水平,但这会弄乱数学。我需要一种方法来欺骗它,使其能够在所有时间内运行所有代码。单次传递时间非常不稳定,调用nanotime()需要时间,因此我需要一个大数字的平均值。

问题是,您从未使用/引用sineNative返回的结果。JIT编译器足够聪明,可以解决永远不使用返回值的问题,因此它最终将什么也不做。解决这个问题的一个非常简单的方法是为返回值添加一个虚拟检查。(例如if(Math.sin(angle)>1{System.out.println(“不可能!”);})


如果您是这样编写基准测试的,那么最好使用JMH()之类的东西,它会自动为您的返回变量创建一个黑洞,这样JIT编译器就不会优化该值。(参见示例)

问题中引用的您自己的实现似乎在发布的代码中缺失。我们不知道它的准确度是多少,我们不知道在计算三角函数的十几种可能的方法中使用了哪一种。我建议发布一个最小的、完整的、自包含的示例代码,该代码可以复制观察结果,其他人也可以运行。我的在这里不重要。本地方法如何工作是个问题。我不认为你在衡量你认为你在衡量的东西。说您正在使用Eclipse没有多大用处。Eclipse是一个IDE;它是一种用于编译、调试和运行事物以及开发软件的其他任务的工具。更相关的是实际的Java引擎。我不熟悉Java实现,但他们可能有自己的数学例程实现或使用主机系统实现。因此,您必须确定您正在使用的Java实现,并希望熟悉它的人看到这个问题。在4GHz处理器上,即每正弦0.22个CPU周期。你认为这是现实的还是你的测量有问题?
public final class MathTest {
    private static int sysReps = 1_000_000;
    private static double value = 0;
    private static final double DRAD_ANGLE_30 = 0.52359877559829887307710723054658d;
    private static final double DRAD_ANGLE_60 = 1.0471975511965977461542144610932d;
    private static double sineNative(double angle ) {
        int reps = sysReps * 100;
            //int repsDone = 0;
        value = 0;
        long startTime, endTime, timeDif;
        startTime = System.nanoTime();
        for (int index = reps - 1; index >= 0; index--) {
            value = Math.sin(angle);
                //repsDone++;
        }
        endTime = System.nanoTime();
        timeDif = endTime - startTime;
        System.out.println("sineNative(): " + timeDif + "ns for " + reps + " sine " + value + " of angle " + angle);
            //System.out.println("reps done: "+repsDone);
        return value;
    }
    private static void testSines() {
        sineNative(DRAD_ANGLE_30);
        //sinCosTanNew6(IBIT_ANGLE_30);
    }
        /* Warm Up */
    private static void repeatAll(int reps) {
        for (int index = reps - 1; index >= 0; index--) {
            testSines();
        }
    }
    public static void main(String[] args) {
        repeatAll(10);
    }
}