先看代码:
问题:两个循环表达式哪个的效率更高一些?
一般写程序的时候用第一种方式的情况较少,这是基本的编程风格要求之一。但是效率有何差别? 根据编译原理上的知识,编译器有可能对这种运算进行优化。测试了一下:
显然编译器没有预期的对代码进行优化。其实思考一下,这种情况下编译器并不能确定这是一个循环不变运算,因为它不能对方法调用的结果进行假设。
- public class Test {
- public static void main(String[] args) {
- for (int i = 0; i < get(); i++) {
- System.out.println("Hello world");
- }
- System.out.println("-----------");
- int k = get();
- for (int i = 0; i < k; i++) {
- System.out.println("test2");
- }
- }
- public static int get() {
- return 5;
- }
- }
一般写程序的时候用第一种方式的情况较少,这是基本的编程风格要求之一。但是效率有何差别? 根据编译原理上的知识,编译器有可能对这种运算进行优化。测试了一下:
- Compiled from "Test.java"
- public class Test extends java.lang.Object{
- public Test();
- Code:
- 0: aload_0
- 1: invokespecial #1; //Method java/lang/Object."<init>":()V
- 4: return
- public static void main(java.lang.String[]);
- Code:
- 0: iconst_0
- 1: istore_1
- 2: iload_1
- 3: invokestatic #2; //Method get:()I
- 6: if_icmpge 23
- 9: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
- 12: ldc #4; //String Hello world
- 14: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
- 17: iinc 1, 1
- 20: goto 2
- 23: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
- 26: ldc #6; //String -----------
- 28: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
- 31: invokestatic #2; //Method get:()I
- 34: istore_1
- 35: iconst_0
- 36: istore_2
- 37: iload_2
- 38: iload_1
- 39: if_icmpge 56
- 42: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
- 45: ldc #7; //String test2
- 47: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
- 50: iinc 2, 1
- 53: goto 37
- 56: return
- public static int get();
- Code:
- 0: iconst_5
- 1: ireturn
- }