Chinaunix首页 | 论坛 | 博客
  • 博客访问: 810994
  • 博文数量: 210
  • 博客积分: 10002
  • 博客等级: 上将
  • 技术积分: 1840
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-18 09:56
文章分类

全部博文(210)

文章存档

2011年(1)

2010年(6)

2009年(65)

2008年(138)

我的朋友

分类: LINUX

2008-11-18 10:40:52

If you're used to the optimizing capabilities of modern C/C++ compilers, you're in for a shock when you first take a look (via javap -c) at the output of a Java compiler. This list of optimizations that currently have to be done by hand should get shorter as Java compilers improve. For each optimization I give before-and-after Java code fragments, and the relevant bytecode (typically an inner loop) that they compile to.

Note that javac -O can generate illegal code by inlining things that it shouldn't (tip from ). Running Geoff's code through Visual Cafe and Visual J++ shows that Symantec has the same problem, but Microsoft doesn't. See also the excellent from .

Also, tools such as preEmptive's will now do most of these missing optimizations for you. [NEW]

Loop invariant code motion:
If an expression inside a loop doesn't change after the loop is entered (i.e. it's invariant), calculate the value of the expression outside the loop and assign it to a temporary variable. Then use the temporary variable within the loop. Note that we could also treat a.length as a loop invariant-- has seen speed improvments of 7-11% in tight loops, in both interpreted and JIT-compiled VMs.
for (i = 0; i < a.length; i++) {     float tmp = c * d;
  b[i] = a[i] + c * d;               for (i = 0; i < a.length; i++) {
}                                      b[i] = a[i] + tmp;
                                     }

 6 aload_2                           12 aload_2
 7 iload 5                           13 iload 6
 9 aload_1                           15 aload_1
10 iload 5                           16 iload 6
12 faload                            18 faload
13 fload_3                           19 fload 5
14 fload 4                           21 fadd
16 fmul                              22 fastore
17 fadd                              23 iinc 6 1
18 fastore                           26 iload 6
19 iinc 5 1                          28 aload_1
22 iload 5                           29 arraylength
24 aload_1                           30 if_icmplt 12
25 arraylength
26 if_icmplt 6

If an expensive expression (for example, the result of a method call) is used more than once within a block of code, calculate it once and put it into a temporary variable for subsequent reuse.
double d = a * Math.sqrt (c);        double tmp = Math.sqrt (c);
double e = b * Math.sqrt (c);        double d = a * tmp;
                                     double e = b * tmp;

 0 dload_1                            0 dload 5
 1 dload 5                            2 invokestatic #5 

Use cheaper operations in place of expensive ones. For example, use compound assignment operators such as += instead of ...=...+..., since they result in fewer bytecode instructions. You can also use shifts instead of multiplication by powers of two, multiplication instead of exponentiation, etc, although mathematical optimizations of this type generally have little benefit unless you're using a just-in-time compiler.
for (i = 0; i < a.length; i++) {     for (i = 0; i < a.length; i++) {
  a[i] = a[i] + x;                     a[i] += x;
}                                    }

 5 aload_1                            5 aload_1
 6 iload_3                            6 iload_3
 7 aload_1                            7 dup2
 8 iload_3                            8 iaload
 9 iaload                             9 iload_2
10 iload_2                           10 iadd
11 iadd                              11 iastore
12 iastore                           12 iinc 3 1
13 iinc 3 1                          15 iload_3
16 iload_3                           16 aload_1
17 aload_1                           17 arraylength
18 arraylength                       18 if_icmplt 5
19 if_icmplt 5
Adding extra reference variables to allow the compiler to eliminate opcodes or use faster bytecodes can also be considered a case of strength reduction. For example, if you're repeatedly accessing elements in a single row of a 2D array, make a 1D array variable that points to that row. See class dgefa in for an example of this optimization -- it saves you an iload and an aaload on each reference.

Similarly, if you have a subclass that performs lots of operations on an object defined in its superclass, making a reference to the object in the subclass with super and then using that reference directly will enable the compiler to replace getfield opcodes with aload opcodes (tip from ).

Variable allocation:
For desperate optimizers only. The first four numeric variables or arguments in a method are accessed using via shorter bytecode instructions, although only three are usable in non-static methods. If you declare your most frequently-used variables first (e.g., loop indices), the inner bytecode loops of your methods will be marginally shorter and possibly faster. Note that although the number of bytecodes for the inner loop is the same, the length of the bytecode has decreased.
int[] a = (int[]) pop ();            int i;
int[] b = (int[]) pop ();            int[] a = (int[]) pop ();
int[] dst = new int[a.length];       int[] b = (int[]) pop ();
int i;                               int[] dst = new int[a.length];

for (i = 0; i < a.length; i++) {      for (i = 0; i < a.length; i++) {
  dst[i] = a[i] + b[i];                dst[i] = a[i] + b[i];
}                                    }

27 aload_3                           27 aload 4
28 iload 4                           29 iload_1
30 aload_1                           30 aload_2
31 iload 4                           31 iload_1
33 iaload                            32 iaload
34 aload_2                           33 aload_3
35 iload 4                           34 iload_1
37 iaload                            35 iaload
38 iadd                              36 iadd
39 iastore                           37 iastore
40 iinc 4 1                          38 iinc 1 1
43 iload 4                           41 iload_1
45 aload_1                           42 aload_2
46 arraylength                       43 arraylength
47 if_icmplt 27                      44 if_icmplt 27
阅读(706) | 评论(0) | 转发(0) |
0

上一篇:实时 Java 系列

下一篇:java performance optimize

给主人留下些什么吧!~~