CHAPTER 1: Optimizing Java Code
3
002564: 7110 3d00 0000 |0006: invoke-static {v0},
Lcom/apress/proandroid/Fibonacci;.computeRecursively:(I)J
00256a: 0b00 |0009: move-result-wide v0
00256c: 9102 0402 |000a: sub-int v2, v4, v2
002570: 7110 3d00 0200 |000c: invoke-static {v2},
Lcom/apress/proandroid/Fibonacci;.computeRecursively:(I)J
002576: 0b02 |000f: move-result-wide v2
002578: bb20 |0010: add-long/2addr v0, v2
00257a: 1000 |0011: return-wide v0
00257c: 8140 |0012: int-to-long v0, v4
00257e: 28fe |0013: goto 0011 // -0002
The first number on each line specifies the absolute position of the code within the file.
Except on the very first line (which shows the method name), it is then followed by one
or more 16-bit bytecode units, followed by the position of the code within the method
itself (relative position, or label), the opcode mnemonic and finally the opcode’s
parameter(s). For example, the two bytecode units 3724 1100 at address 0x00255a
translate to “if-le v4, v2, 0012 // +0011”, which basically means “if content of virtual
register v4 is less than or equal to content of virtual register v2 then go to label 0x0012
by skipping 17 bytecode units” (17
10
equals 11
16
). The term “virtual register” refers to the
fact that these are not actual hardware registers but instead the registers used by the
Dalvik virtual machine.
Typically, you would not need to look at your application’s bytecode. This is especially
true with Android 2.2 (codename Froyo) and later versions since a Just-In-Time (JIT)
compiler was introduced in Android 2.2. The Dalvik JIT compiler compiles the Dalvik
bytecode into native code, which can execute significantly faster. A JIT compiler
(sometimes referred to simply as a JIT) improves performance dramatically because:
Native code is directly executed by the CPU without having to be
interpreted by a virtual machine.
Native code can be optimized for a specific architecture.
Benchmarks done by Google showed code executes 2 to 5 times faster with
Android 2.2 than Android 2.1. While the results may vary depending on what
your code does, you can expect a significant increase in speed when using
Android 2.2 and later versions.
The absence of a JIT compiler in Android 2.1 and earlier versions may affect
your optimization strategy significantly. If you intend to target devices running
Android 1.5 (codename Cupcake), 1.6 (codename Donut), or 2.1 (codename
Éclair), most likely you will need to review more carefully what you want or
need to provide in your application. Moreover, devices running these earlier
Android versions are older devices, which are less powerful than newer ones.
While the market share of Android 2.1 and earlier devices is shrinking, they still
represent about 12% as of December 2011). Possible strategies are:
Don’t optimize at all. Your application could be quite slow on these
older devices.