java中的快速正弦和余弦函数

我知道Math.sin()Math.cos()函数,但我想知道是否有一种方法可以创建(或使用已经存在的)更快的函数,因为我不关心精确定位准确性。 我正在寻求执行基本的sin或cos计算,并使其基本上尽可能快地执行。 简单地迭代西格玛几次比Math.sin()更快?

由于你不太关心准确性将它存储在预先计算或只计算一次的表中,所以当我想避免调用Math时这就是我所做的事情。

大致

 public class CosSineTable { double[] cos = new double[361]; double[] sin = new double[361]; private static CosSineTable table = new CosSineTable(); private CosSineTable() { for (int i = 0; i <= 360; i++) { cos[i] = Math.cos(Math.toRadians(i)); sin[i] = Math.sin(Math.toRadians(i)); } } public double getSine(int angle) { int angleCircle = angle % 360; return sin[angleCircle]; } public double getCos(int angle) { int angleCircle = angle % 360; return cos[angleCircle]; } public static CosSineTable getTable() { return table; } } 

我将循环和方法的优化留给您。

预先计算的表格是要走的路。 这是一个实现:

 static final int precision = 100; // gradations per degree, adjust to suit static final int modulus = 360*precision; static final float[] sin = new float[modulus]; // lookup table static { // a static initializer fills the table // in this implementation, units are in degrees for (int i = 0; i=0 ? sin[a%(modulus)] : -sin[-a%(modulus)]; } // These are your working functions: public static float sin(float a) { return sinLookup((int)(a * precision + 0.5f)); } public static float cos(float a) { return sinLookup((int)((a+90f) * precision + 0.5f)); } 

在我的笔记本电脑上,这些速度比Math.sin快6倍。

我只使用了一张表 – 将余弦变成正弦的成本并不明显。

我使用了浮点数,假设你在计算中可能会使用浮点数,因为你对性能的偏好超过了精度。 这里没有太大区别,因为瓶颈实际上只是数组查找。

这是我的基准:

 public static void main(String[] args) { int reps = 1<<23; int sets = 4; Q.pl(" Trial sinTab cosTab sinLib"); for(int i = 0; i 

输出:

  Trial sinTab cosTab sinLib 0 102.51 111.19 596.57 1 93.72 92.20 578.22 2 100.06 107.20 600.68 3 103.65 102.67 629.86 

你可以试试http://sourceforge.net/projects/jafama/

它使用查找表,因此它实际上可能比Math慢,特别是如果表经常从CPU缓存中逐出,但对于数千次连续调用,它可能会更快。

在类加载期间它似乎也慢一些(也许JIT还没有开始),所以你可能想在那个特定的用例中避​​免它。

我知道这个问题很老,但我认为这是最快的java实现,可以精确到65536个元素。

 public class MathHelper { private static double[] a = new double[65536]; public static final double sin(float f) { return a[(int) (f * 10430.378F) & '\uffff']; } public static final double cos(float f) { return a[(int) (f * 10430.378F + 16384.0F) & '\uffff']; } static { for (int i = 0; i < 65536; ++i) { a[i] = Math.sin((double) i * 3.141592653589793D * 2.0D / 65536.0D); } } } 

资料来源: https : //github.com/Bukkit/mc-dev/blob/master/net/minecraft/server/MathHelper.java