![]() |
1
15
here )。这是Math.exp()的近似值,复制自 this blog posting :
它基本上与具有2048个条目和条目之间的线性插值的查找表相同,但所有这些都使用IEEE浮点技巧。它比我机器上的Math.exp()快5倍,但如果使用-server编译,速度可能会有很大的变化。 |
![]() |
2
12
+1编写自己的exp()实现。就是如果这是 真正地 应用程序中的瓶颈。如果你能处理一些不精确的问题,有很多非常有效的指数估计算法,其中一些可以追溯到几个世纪前。据我所知,Java的exp()实现相当慢,即使对于必须返回“精确”结果的算法也是如此。 哦,不要害怕用纯Java编写exp()实现。JNI有很多开销,JVM能够在运行时优化字节码,有时甚至超过C/C++的能力。 |
![]() |
3
6
使用Java的。 此外,缓存exp的结果,然后您可以比再次计算更快地查找答案。 |
![]() |
4
5
你会想结束任何循环调用的
|
![]() |
5
3
如果分批进行,您可能可以让它运行得更快。进行JNI调用会增加开销,因此您不希望对需要计算的每个exp()都进行调用。我会尝试传递一个包含100个值的数组,然后得到结果,看看它是否有助于提高性能。 |
![]() |
6
2
真正的问题是,这是否成为你的瓶颈?您是否分析过您的应用程序并发现这是导致速度减慢的主要原因?
|
![]() |
7
2
Commons Math3
随附优化版本:
Fabien
以下是javadoc:
方法:
精度:计算以63位精度完成,因此结果应正确四舍五入到99.9%的输入值,否则ULP误差小于1。 |
![]() |
8
0
由于Java代码将通过实时(JIT)编译器编译为本机代码,因此没有理由使用JNI调用本机代码。 此外,您不应该缓存输入参数为浮点实数的方法的结果。在时间上获得的收益将在使用的空间量上损失很多。 |
![]() |
9
0
使用JNI的问题是调用JNI所涉及的开销。Java虚拟机现在已经非常优化了,对内置Math.exp()的调用会自动优化为直接调用C exp()函数,甚至可以优化为直接的x87浮点汇编指令。 |
![]() |
10
0
http://java.sun.com/docs/books/performance/1st_edition/html/JPNativeCode.fm.html 因此,正如其他人所建议的,尝试整理涉及使用JNI的操作。 |
![]() |
11
0
写你自己的,适合你的需要。 例如,如果你所有的指数都是二的幂,你可以使用位移位。如果使用有限范围或一组值,则可以使用查找表。如果您不需要针点精度,可以使用不精确但更快的算法。 |
![]() |
12
0
跨越JNI边界进行调用会带来成本。 如果您可以将调用exp()的循环也移动到本机代码中,这样就只有一个本机调用,那么您可能会得到更好的结果,但我怀疑它会比纯Java解决方案快得多。 我不知道应用程序的细节,但是如果调用的可能参数集相当有限,那么可以使用预先计算的查找表来加快Java代码的速度。 |
![]() |
13
0
exp有更快的算法,这取决于您的目标。问题空间是否限制在某个范围内,您是否只需要某个分辨率、精度或精度等。
-亚当 |
![]() |
14
0
超越函数总是比加法或乘法慢得多,这是一个众所周知的瓶颈。如果您知道您的值在一个狭窄的范围内,您可以简单地构建一个查找表(两个排序数组;一个输入,一个输出)。使用Arrays.binarySearch查找正确的索引,并使用[index]和[index+1]处的元素插值。 另一种方法是分割数字。让我们以3.81为例,将其拆分为3+0.81。
1+x+x^2/2+x^3/6+x^4/24。。。。等 为精确起见,尽可能多地使用术语;不幸的是,如果x接近1,速度会变慢。假设您转到x^4,则得到2.2445,而不是正确的2.2448 然后将结果2.781^3=20.08乘以2.781^0.81=2.2445,得到结果 45.07,误差为两千分之一(正确:45.15)。 |
![]() |
15
0
|