Java “对绩效的影响”;“太多”;方法中的局部变量?

Java “对绩效的影响”;“太多”;方法中的局部变量?,java,android,performance,dalvik,local-variables,Java,Android,Performance,Dalvik,Local Variables,我被指派扩展软件的某个组件(由其他人编写)。它是为Android编写的,完全使用Java(据我所知,它没有本机/c++组件) 在熟悉代码时,我遇到了一个方法(渲染类的绘图方法)。该方法涉及一个更新对象的大循环(然后另一个方法将在稍后渲染它们)。该方法的创建者似乎在循环之前将所有/大多数成员变量和数组以及其他对象的字段缓存到局部变量中。代码如下所示: float[] coordArr = mCoordArr; float[] texCoordArr = mTexCoordArr;

我被指派扩展软件的某个组件(由其他人编写)。它是为Android编写的,完全使用Java(据我所知,它没有本机/c++组件)

在熟悉代码时,我遇到了一个方法(渲染类的绘图方法)。该方法涉及一个更新对象的大循环(然后另一个方法将在稍后渲染它们)。该方法的创建者似乎在循环之前将所有/大多数成员变量和数组以及其他对象的字段缓存到局部变量中。代码如下所示:

    float[] coordArr = mCoordArr;
    float[] texCoordArr = mTexCoordArr;
    float[] cArray = mColArray;

    // ... there are further locals too, I didn't copy all here

    float[] color = mColor;
    float r = color[0];
    float g = color[1];
    float b = color[2];
    float a = color[3];

    int texw = mTexW;
    int texH = mTexH;
    Font font = mFont;
    float[] ccords = font.ccords;
    float cf = font.cf;
    float cu = font.cu;
    int len = mCurLength;

    // Update the objects
    for (int i = 0; i < len; ++i) {

        // A quite big loop body

        // ... all locals are accessed from the loop

    }
float[]coordArr=mCoordArr;
float[]texCoordArr=mTexCoordArr;
float[]cArray=mcolaray;
// ... 还有更多的当地人,我没有在这里全部抄袭
float[]color=mColor;
浮动r=颜色[0];
浮点数g=颜色[1];
浮动b=颜色[2];
浮动a=颜色[3];
int-texw=mTexW;
int-texH=mTexH;
Font=mFont;
float[]ccords=font.ccords;
float cf=font.cf;
float cu=font.cu;
int len=mCurLength;
//更新对象
对于(int i=0;i
渲染组件是单线程的,包含其所有成员变量

我用Java/Dalvik反汇编程序检查了它,字节码注释说该方法使用了41个寄存器。我假设作者将它们缓存到本地,以帮助JIT,并为字段/数组访问节省一些时间,但是这不是因为本地数量太多而影响性能吗?例如,我听说过“注册压力”

我只是不想在没有必要的情况下重写代码(即,如果当前代码是正确的),为了分析它,我需要重写它(否则只有一个版本——当前版本,因此没有什么可比较的…)


如果不鼓励使用“太多”局部变量,那么是否存在不应超过的“最佳”最大值?(当然,我知道系统的堆栈大小是硬限制的。)因为如果是这样的话,我可能也需要修改软件的其他部分(如果原始作者非常友好地将所有内容都放入局部变量中)。

而大量局部变量可能会导致“寄存器压力”,这仅仅意味着编译器可能会进行更多的内存提取。然而,替代方法是(例如)用
color[0]
替换对
r
的引用,这在理论上涉及索引检查和间接获取,这可能导致比寄存器短缺更多的内存获取

简言之,没有简单的答案

所以,我倾向于不去管代码,特别是如果

  • 有证据表明,原始/先前作者是通过分析得出当前设计的,或

  • 代码已经运行得足够快了


是否像在动画中那样对后期状态执行此操作?请注意:@pst:谢谢。我发现其中有一个有趣的部分(见我在Stephen C回答下面的评论)。我对Dalvik和VM机制没有太多经验,因此不确定如何解释引用的部分。我在三星Galaxy S3上没有遇到性能问题,但我也将在周一在其他手机上测试它。顺便说一句,引用我在评论中收到的Dalvik链接:“因为在实践中,一个方法需要超过16个寄存器是不常见的,而且需要超过8个寄存器是相当常见的,所以许多指令仅限于处理前16个寄存器。[..]在指令变量无法寻址所需寄存器的情况下,预计寄存器内容会从原始寄存器移到低寄存器(操作之前).................................和/或从低结果寄存器移到高寄存器(操作之后)。“这会不会以某种方式增加JIT/性能的负担?在Galaxy S3上,JIT功能强大,但该软件也必须在一些较旧版本的平台上运行(将在周一进行测试)。@ThomasCalc-“这会以某种方式增加JIT/性能的负担吗?”。可以。但是你也需要考虑摆脱缓存的另一面;见上文。还请记住,硬件和/或JIT编译器的差异可能会挫败您进行优化的尝试。“将在周一进行测试”我很好奇,这些测试显示了什么?@aeracode-他们可能显示了本周没有周一:-)