我致力于Android JAVA和Android NDK应用程序之间的性能差异。 我在超过90000个顶点上执行了Matrix4D-Vector4D转换,作为3D图形的示例。
值得注意的是,JAVA版本比C版本差不多 100倍。我错了吗?有没有人有类似的经历?
我的Java代码转换:
long t1 = System.nanoTime();
for ( int i = 0; i < vCount; i++)
{
Vector4 vOut = new Vector4();
Vector4 v = vertices[i];
vOut.v_[0] = v.v_[0] * matrix[0].v_[0];
vOut.v_[1] = v.v_[0] * matrix[0].v_[1];
vOut.v_[2] = v.v_[0] * matrix[0].v_[2];
vOut.v_[3] = v.v_[0] * matrix[0].v_[3];
vOut.v_[0] += v.v_[1] * matrix[1].v_[0];
vOut.v_[1] += v.v_[1] * matrix[1].v_[1];
vOut.v_[2] += v.v_[1] * matrix[1].v_[2];
vOut.v_[3] += v.v_[1] * matrix[1].v_[3];
vOut.v_[0] += v.v_[2] * matrix[2].v_[0];
vOut.v_[1] += v.v_[2] * matrix[2].v_[1];
vOut.v_[2] += v.v_[2] * matrix[2].v_[2];
vOut.v_[3] += v.v_[2] * matrix[2].v_[3];
vOut.v_[0] += v.v_[3] * matrix[3].v_[0];
vOut.v_[1] += v.v_[3] * matrix[3].v_[1];
vOut.v_[2] += v.v_[3] * matrix[3].v_[2];
vOut.v_[3] += v.v_[3] * matrix[3].v_[3];
vertices[i] = vOut;
}
long t2 = System.nanoTime();
long diff = t2 - t1;
double ms = (double)(diff / 1000000.0f);
Log.w("GL2JNIView", String.format("ms %.2f ", ms));
性能(转换&gt; 90 000顶点| Android 4.0.4 SGS II): (200次运行的中值)
JAVA-Version: 2 FPS
C-Version: 190 FPS
答案 0 :(得分:5)
在每次迭代中创建一个新的Vector4。根据我自己的经验,使用新的内部循环可能会导致Android中出现意外的性能问题。
答案 1 :(得分:0)
AFAIK,Android Java实现是通过一个名为Dalvik的虚拟机,它具有与JVM不同的指令集,并且不使用任何just-in-time compilation技术将一些字节码动态转换为机器代码,但只是解释它们。所以Dalvik显然在CPU绑定任务上比C慢。
这可能会在最近的Android系统中发生变化。
答案 2 :(得分:0)
你也应该改变你的循环。除了@ toopok4k3的答案,你应该尝试这些:
我假设下面的版本中的值是双倍的。
int i = 0;
try
{
Vector4 vOut = new Vector4();
final double m0v0 = matrix[0].v_[0];
final double m0v1 = matrix[0].v_[1];
final double m0v2 = matrix[0].v_[2];
final double m0v3 = matrix[0].v_[3];
final double m1v0 = matrix[1].v_[0];
final double m1v1 = matrix[1].v_[1];
final double m1v2 = matrix[1].v_[2];
final double m1v3 = matrix[1].v_[3];
final double m2v0 = matrix[2].v_[0];
final double m2v1 = matrix[2].v_[1];
final double m2v2 = matrix[2].v_[2];
final double m2v3 = matrix[2].v_[3];
final double m3v0 = matrix[3].v_[0];
final double m3v1 = matrix[3].v_[1];
final double m3v2 = matrix[3].v_[2];
final double m3v3 = matrix[3].v_[3];
while (true)
{
Vector4 v = vertices[i];
i++;
double vertexVal = v.v_[0];
vOut.v_[0] = vertexVal * m0v0;
vOut.v_[1] = vertexVal * m0v1;
vOut.v_[2] = vertexVal * m0v2;
vOut.v_[3] = vertexVal * m0v3;
vertexVal = v.v_[1];
vOut.v_[0] += vertexVal * m1v0;
vOut.v_[1] += vertexVal * m1v1;
vOut.v_[2] += vertexVal * m1v2;
vOut.v_[3] += vertexVal * m1v3;
vertexVal = v.v_[2];
vOut.v_[0] += vertexVal * m2v0;
vOut.v_[1] += vertexVal * m2v1;
vOut.v_[2] += vertexVal * m2v2;
vOut.v_[3] += vertexVal * m2v3;
vertexVal = v.v_[3];
vOut.v_[0] += vertexVal * m3v0;
vOut.v_[1] += vertexVal * m3v1;
vOut.v_[2] += vertexVal * m3v2;
vOut.v_[3] += vertexVal * m3v3;
vertices[i] = vOut;
}
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
// loop is done
}