(int)Math.sqrt(n)比(int)Math.floor慢得多(Math.sqrt(n))
我正在查看我的代码,希望改善其性能,然后我看到了这一点:
int sqrt = (int) Math.floor(Math.sqrt(n));
哦,好吧,我并不需要对Math.floor的调用,因为从Math.sqrt(n)返回的double将会有效地铺平数字(因为sqrt永远不会返回负数)。 所以我去了Math.floor的电话:
int sqrt = (int) Math.sqrt(n)
坐下来,自满地看着代码运行并执行大约10%! 比之前的版本差。 这让我感到震惊。 任何想法的人?
Math.floor javadocs:“返回小于或等于参数的最大(最接近正无穷大)double值,并且等于一个数学整数。”
在我的情况下编辑 n是很长的。 任何机会cast-floor-sqrt都会产生与cast-sqrt不同的int吗? 我个人不明白为什么它会......所有涉及的数字都是积极的。
Math.floor方法只是将调用委托给StrictMath.floor方法(请参见此处)。 这种方法是一种本地方法。 在此方法之后,演员不必做任何事情,因为它已经是一个等于整数的数字(所以没有小数位)。
也许本底的执行速度比将double值转换为int值更快。
我无法重现相同的结果。 使用下面这个简单的Java代码,没有调用Math.floor的函数始终更快:
with floor elapsed milliseconds: 7354
without floor elapsed milliseconds: 4252
public class TestCast {
private static final int REPS = Integer.MAX_VALUE / 4;
private static void withFloor() {
long sum = 0;
long start = System.currentTimeMillis();
for (int i = REPS; i != 0; --i) {
sum += (int)Math.floor(Math.sqrt(i));
}
long end = System.currentTimeMillis();
long elapsed = end - start;
System.out.println("with floor elapsed milliseconds: " + elapsed);
System.out.println(sum);
}
private static void withoutFloor() {
long sum = 0;
long start = System.currentTimeMillis();
for (int i = REPS; i != 0; --i) {
sum += (int)Math.sqrt(i);
}
long end = System.currentTimeMillis();
long elapsed = end - start;
System.out.println("without floor elapsed milliseconds: " + elapsed);
System.out.println(sum);
}
public static void main(String[] args) {
withFloor();
withoutFloor();
}
}
另外,查看反汇编的字节码,我们可以清楚地看到在第一个函数中调用Math.floor,而在第二个函数中没有调用。 代码中必须有其他内容。 也许你可以发布你的代码或缩短版本,以显示你所看到的结果。
private static void withFloor();
Code:
0: lconst_0
1: lstore_0
2: invokestatic #2 // Method java/lang/System.currentTimeMillis:()J
5: lstore_2
6: ldc #3 // int 536870911
8: istore 4
10: iload 4
12: ifeq 35
15: lload_0
16: iload 4
18: i2d
19: invokestatic #4 // Method java/lang/Math.sqrt:(D)D
22: invokestatic #5 // Method java/lang/Math.floor:(D)D
25: d2i
26: i2l
27: ladd
28: lstore_0
29: iinc 4, -1
32: goto 10
35: invokestatic #2 // Method java/lang/System.currentTimeMillis:()J
38: lstore 4
40: lload 4
42: lload_2
43: lsub
44: lstore 6
46: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
49: new #7 // class java/lang/StringBuilder
52: dup
53: invokespecial #8 // Method java/lang/StringBuilder."<init>":()V
56: ldc #9 // String with floor elapsed milliseconds:
58: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
61: lload 6
63: invokevirtual #11 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
66: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
69: invokevirtual #13 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
72: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
75: lload_0
76: invokevirtual #14 // Method java/io/PrintStream.println:(J)V
79: return
private static void withoutFloor();
Code:
0: lconst_0
1: lstore_0
2: invokestatic #2 // Method java/lang/System.currentTimeMillis:()J
5: lstore_2
6: ldc #3 // int 536870911
8: istore 4
10: iload 4
12: ifeq 32
15: lload_0
16: iload 4
18: i2d
19: invokestatic #4 // Method java/lang/Math.sqrt:(D)D
22: d2i
23: i2l
24: ladd
25: lstore_0
26: iinc 4, -1
29: goto 10
32: invokestatic #2 // Method java/lang/System.currentTimeMillis:()J
35: lstore 4
37: lload 4
39: lload_2
40: lsub
41: lstore 6
43: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
46: new #7 // class java/lang/StringBuilder
49: dup
50: invokespecial #8 // Method java/lang/StringBuilder."<init>":()V
53: ldc #15 // String without floor elapsed milliseconds:
55: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
58: lload 6
60: invokevirtual #11 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
63: invokevirtual #12 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
66: invokevirtual #13 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
69: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
72: lload_0
73: invokevirtual #14 // Method java/io/PrintStream.println:(J)V
76: return
链接地址: http://www.djcxy.com/p/15201.html
上一篇: (int) Math.sqrt(n) much slower than (int) Math.floor(Math.sqrt(n))