我目前正在研究一些 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
与我有关的部分是将实例字段的值读入寄存器 v1 的 iget 操作码。相同的字段是从前面操作码中相同的 v1 寄存器写入的,因此操作码看起来完全是多余的。
我唯一能想到的就是这样做是为了使这更加线程安全。但肯定这应该是程序员的责任(通过使用同步块)而不是编译器的责任。尽管我不能 100% 确定,但我认为上述行为与大多数 C/C++ 编译器的行为完全不同。
我应该说,使用 ProGuard 时产生的 dex 基本相同。我还应该提到我正在使用最新的 Android 工具和最新型号的 JDK。