可以加快这个java代码的速度吗?

时间:2012-10-29 20:06:01

标签: java optimization

我在Android应用程序中有一些代码,当我分析我的应用程序时,它占用了大部分时间。我试图优化它,但仍占用大部分CPU时间。我想知道是否有人对如何加快这一点有任何想法。这是使用以下代码Im的精简版本:

输入:
d是数组浮点数
a是数组浮点数 e是数组浮点数

输出:
out是3个浮点数的数组

代码:

float [] c=new float[3];
float [] b=new float[3];
float [] out=new float[3];

c[0] = a[0] - d[0 * 4 + 3];
c[1] = a[1] - d[1 * 4 + 3];
c[2] = a[2] - d[2 * 4 + 3];

b[0] = c[0]*d[0 * 4 + 0] + c[1]*d[1 * 4 + 0] + c[2]*d[2 * 4 + 0];
b[1] = c[0]*d[0 * 4 + 1] + c[1]*d[1 * 4 + 1] + c[2]*d[2 * 4 + 1];
b[2] = c[0]*d[0 * 4 + 2] + c[1]*d[1 * 4 + 2] + c[2]*d[2 * 4 + 2];           

out[0] = b[0] * e[0 * 4 + 0] + b[1] * e[0 * 4 + 1] + b[2] * e[0 * 4 + 2] + e[0 * 4 + 3];
out[1] = b[0] * e[1 * 4 + 0] + b[1] * e[1 * 4 + 1] + b[2] * e[1 * 4 + 2] + e[1 * 4 + 3];
out[2] = b[0] * e[2 * 4 + 0] + b[1] * e[2 * 4 + 1] + b[2] * e[2 * 4 + 2] + e[2 * 4 + 3];

对于那些对其3D模型动画的顶点变换感兴趣的人。 'out'是变换后的顶点,'a'原始顶点。其余的数组是骨架联合信息。

4 个答案:

答案 0 :(得分:1)

其余代码的作用是什么?这看起来像一小段代码,所以它应该执行得非常快。你真的遇到性能问题,还是试图让你的程序根本没用CPU?

那就是说,你可以简单地预先计算所有那些简单的算术运算:

c[0] = a[0] - d[3];
c[1] = a[1] - d[7];
c[2] = a[2] - d[11];

我不明白你如何访问d[3]d[7]d[11],因为d应该是一个包含3个元素的数组。

答案 1 :(得分:0)

你无能为力。所有的操作都是赋值和数学,你没有实现它们。另外,这些操作已经非常快......在某种类型的for循环中执行此操作会更高效,因为java必须在乘法之前存储所有这些数字。动态地做更有效。

答案 2 :(得分:0)

一次乘以零可以简化为零,然后删除添加,但我相信他们的编译器或热点已经可以做到。

您可以尝试memoising结果以防止重新计算。

此外,您可以尝试使用JCuda将此类数学计算机卸载到GPU中,但我不知道Android是否支持此类数据。

答案 3 :(得分:0)

所有编译时常量将(必须)由编译器进行常量折叠。您所能做的就是消除临时数组,无论如何您都不会将其用作数组。我试过这样的话:

public float[]  transform2(float[] a, float[] d, float[] e)
{
    float c0,c1,c2;
    float b0,b1,b2;
    float [] out=new float[3];

    c0 = a[0] - d[0 * 4 + 3];
    c1 = a[1] - d[1 * 4 + 3];
    c2 = a[2] - d[2 * 4 + 3];

    b0 = c0*d[0 * 4 + 0] + c1*d[1 * 4 + 0] + c2*d[2 * 4 + 0];
    b1 = c0*d[0 * 4 + 1] + c1*d[1 * 4 + 1] + c2*d[2 * 4 + 1];
    b2 = c0*d[0 * 4 + 2] + c1*d[1 * 4 + 2] + c2*d[2 * 4 + 2];           

    out[0] = b0 * e[0 * 4 + 0] + b1 * e[0 * 4 + 1] + b2 * e[0 * 4 + 2] + e[0 * 4 + 3];
    out[1] = b0 * e[1 * 4 + 0] + b1 * e[1 * 4 + 1] + b2 * e[1 * 4 + 2] + e[1 * 4 + 3];
    out[2] = b0 * e[2 * 4 + 0] + b1 * e[2 * 4 + 1] + b2 * e[2 * 4 + 2] + e[2 * 4 + 3];

    return out;
}

您的代码需要35665毫秒来运行10000000000L次迭代。 transform2()花了20077ms所以它的速度有点快了两倍。两种方法都先预热,a [],d []和e []包含随机浮点数。

我想知道是否有可能通过使out参数而不是在方法内部分配来改进事物,如果out可以在外部保存,但在您的调用中可能无法实现码。然而,将其添加为第四个参数会使其更糟糕:它必须撤消一些HotSpot优化。但是当你在Android上时,如果可行,你可以考虑这个。

那是很多迭代......