值得注意的是,监视一个方法会带来一些开销,在VisualVM中尤其如此。如果你有一个被频繁调用但实际操作很少的方法,它可能会看起来占用大量CPU资源,例如我曾经看到过Integer.hashCode()的CPU使用率非常高;)
在我的机器上,一个floor操作需要不到5.6纳秒,而一个cast操作只需要2.3纳秒。你也可以在你的机器上试一下。
除非你需要处理特殊情况,否则使用普通的cast操作速度更快。
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
StrictMath.*
(通常比更准确的Math.*
慢) - 如果需要对floor进行重复计算,则可以将结果缓存到映射中。 - NishantMath.floor()
函数?您处理哪种类型的数字?另外,C++ 或 MATLAB 在数学运算方面更快并不奇怪。 - posdefMath.floor()
委托给了StrictMath.floor()
,请参见:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Math.java#Math.floor%28double%29 - posdefStrictMath
使用本地方法 --public static native double floor(double a);
- Nishantfloor()
被认为非常慢。并不是因为取整操作本身很慢,而是因为需要检查和处理许多边角情况。虽然有位运算技巧可以使其极其快速,但仍需注意许多细节。SSE4.1指令集添加了原生的舍入操作指令,包括floor()
。但要访问这些指令,需要使用具有编译器内部函数或者汇编语言的C/C++。 - Mysticial