我目前正在研究一些Android性能问题,发现dex代码中存在一些次优模式。我想知道这是否是可预期的,并且背后的理由是什么。
例如,考虑以下Java代码:
m_testField += i;
doSomething(m_testField);
当这个被构建并且通过baksmali运行时,它看起来像下面这样:
iget v1, p0, Lcom/example/MainActivity$FieldTest;->m_testField:I
add-int/2addr v1, v0
iput v1, p0, Lcom/example/MainActivity$FieldTest;->m_testField:I
iget v1, p0, Lcom/example/MainActivity$FieldTest;->m_testField:I
invoke-direct {p0, v1}, Lcom/example/MainActivity$FieldTest;->doSomething(I)V
我担心的部分是iget操作码,它将实例字段的值读入寄存器v1。在前一个操作码中,相同的字段是从完全相同的v1寄存器中写入的,所以这个操作码似乎是完全多余的。
唯一能想到的是这样做是为了使它更加线程安全。但是这应该是程序员的责任(通过使用同步块),而不是编译器的责任。虽然我不能百分之百确定,但我认为上述行为与大多数C / C ++编译器所做的事情非常不同。
我应该说,当使用ProGuard时会生成基本相同的dex。我也应该提到,我正在使用最新的Android工具和晚期型号的JDK。