首页 > 解决方案 > 通过在 Java 中重新使用浮点数组是否有显着的 GC 性能提升?

问题描述

我正在用 Java 开发一个 Android 游戏,垃圾收集器经常启动并导致延迟峰值。

在查看了我的对象分配之后,被回收的大部分是 float[]。我为多个对象每帧创建一个新的 float[] 。

重新使用 float[] 是否有意义,或者它对性能的影响微不足道(尤其是与对象相比)。

public float[] rectangleToVerts(float x, float y, float width, float height) 
    float[] verts = new float[8];

    verts[0] = x - width / 2;
    verts[1] = y + height / 2;
    verts[2] = x + width / 2;
    verts[3] = y + height / 2;
    verts[4] = x + width / 2;
    verts[5] = y - height / 2;
    verts[6] = x - width / 2;
    verts[7] = y - height / 2;

    return verts;
}

public void tick(){
    shape.setVertices(rectangleToVerts(x, y, 5, 5);
}

相对

public float[] rectangleToVerts(float x, float y, float width, float 
    height, float[] verts) 

    verts[0] = x - width / 2;
    verts[1] = y + height / 2;
    verts[2] = x + width / 2;
    verts[3] = y + height / 2;
    verts[4] = x + width / 2;
    verts[5] = y - height / 2;
    verts[6] = x - width / 2;
    verts[7] = y - height / 2;

    return verts;
}

private float[8] verts;

public void tick(){
    shape.setVertices(rectangleToVerts(x, y, 5, 5, verts);
}

标签: java

解决方案


很难确切地说第二个示例中的代码效率会提高多少,但它肯定更有效。每个数组本身就是一个对象,您创建的新引用越少,垃圾收集器运行的频率就越低。既然你说大部分被回收的是 float[] 类型,这似乎是一个可能的候选者。如果您使用的是 Android Studio 3.0 或更高版本,则可以使用Memory Profiler查看程序如何分配内存,并确定这是否确实是导致速度变慢的原因。

附带说明一下,您还要计算每个顶点的值两次。(例如,verts[0] 和 verts[6] 都设置为 x - width / 2。)快速简单的优化可能如下所示:

public float[] rectangleToVerts(float x, float y, float width, float height, float[] verts) 
{
    verts[0] = x - width / 2;
    verts[6] = verts[0];        

    verts[1] = y + height / 2;
    verts[3] = verts[1];

    verts[2] = x + width / 2;
    verts[4] = verts[2];

    verts[5] = y - height / 2;
    verts[7] = verts[5];

    return verts;
}

希望这可以帮助!


推荐阅读