我用卡尺进行了一些微基准测试。在(预先计算的)随机数数组(-4 * pi .... 4 *pi)上进行10000000次迭代。我尽了最大的努力来获得最快的JNI解决方案-
很难预测您是否会真正得到
fsincos仿真
sincos。报告的数字是10项卡尺试验中最好的一项(依次包括3到10次试验,报告了平均值)。大约每个内循环运行30-100次。
我已经对几种变体进行了基准测试:
Math.sin
仅(参考)Math.cos
仅(参考)Math.sin
+Math.cos
sincos
通过JNIMath.sin
+通过Math.sqrt( (1+sin) * (1-sin) )
+符号重建cosMath.cos
+通过Math.sqrt( (1+cos) * (1-cos) )
+符号重建实现犯罪
(1+sin)*(1-sin)=1-sin*sin从数学上讲,但是如果sin接近1,它应该更精确吗?运行时差异最小,您节省了一个附加项。
通过进行符号重建
x %= TWOPI; if (x<0)x+=TWOPI;,然后检查象限。如果您有一个想法,如何用更少的CPU来执行此操作,我将很高兴听到。
sqrt至少对于常见角度而言,数值通孔似乎还可以。从粗略的实验来看,范围为1e-10。
Sin 1,30 ==============Cos 1,29 ==============Sin, Cos 2,52 ============================JNI sincos 1,77 ===================SinSqrt 1,49 ================CosSqrt 1,51 ================
在
sqrt(1-s*s)主场迎战
sqrt((1+s)*(1-s))使得约0.01差别。如您所见,
sqrt基于方法的方法胜过其他方法(因为我们目前无法
sincos在纯Java中访问)。JNI
sincos优于计算
sin和
cos,但是该
sqrt方法仍然更快。
cos本身似乎始终比sick(0,01)更好
sin,但是用于区分符号的大小写区分需要额外的
>测试。我不认为我的研究结果支持,要么
sin+sqrt或
cos+sqrt明显preferrable,但他们节省约的40%的时间相比,
sin然后
cos。
如果我们将Java扩展为具有 固有的优化sincos
,那么可能会更好。恕我直言,这是一个常见的用例,例如在图形中。当在AWT,蜡染等中使用时,许多应用程序都可以从中受益。
如果再次运行它,我还将添加JNI
sin和一个
noop以估计JNI的成本。也许还可以
sqrt通过JNI
对这个技巧进行基准测试。只是为了确保我们确实希望
sincos从长远来看具有内在性。



