一个简单的效率问题 void func(int n){ int k=Math.sqrt(n); for(int i=0;i<k;i++){ ..... }----------------------------- void func(int n){ for(int i=0;i<Math.sqrt(n);i++){ ..... }上面两种代码,功能基本一样,哪个效率更高点呢?类似的还有while循环。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 按照编译原理上的原理,循环不变运算应该外提,还以为java编译器会进行优化呢,测试了一下,没有优化。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; }}看生成的class文件内容: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: returnpublic 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: returnpublic static int get(); Code: 0: iconst_5 1: ireturn}看对应第一个循环最后的 20: goto 2,每次循环返回到标号2处,下面都要调用get()方法。也就是说编译器没有进行优化。 这根本不用假设,对于表达式变量根本就不能优化,不是编译器不去优化.因为表达式变量不能确定每次运算的结果是否相同,怎么可能为你优化呢?如果你写(long i = 0;i < System.currentTimeMillis();i++)优化明显违反你的本意,而编译时优化并不能确定哪人表达式的值是固定的.除非本身就是常量表达式. ZangXT和axman都說清楚了,學習了 第一种效率高是很明显的第二种每次进入for循环时都要计算Math.sqrt(n)的值勤 我的建议是改成这样(第 08 行),我们应该局变量的作用范围尽可能地减小。01 public class Test {02 03 public static void main(String[] args) {04 for (int i = 0; i < get(); i++) {05 System.out.println("Hello world");06 }07 System.out.println("-----------");08 for (int i = 0, k = get(); i < k; i++) {09 System.out.println("test2");10 }11 }1213 public static int get() {14 return 5;15 }16 } 这个例子我认为很好啊,可以把 get() 看成是需要进行一系列运算才得出结果的。 第一种的方式效率高。不论是什么语言,不变的变量应该放在外面。因为,在FOR循环中,通过调用函数来得到不变的变量需要消耗资源。 java String处理问题 请大家帮忙,将下面的一个加密和解密的delphi函数改为java函数,谢谢 ClassLoader与memory的问题 java Swing编程的重绘问题,高手请进! 如何在命令行程序下控制光标左移或右移 jni调用C++生成的本地方法中遇到的问题 如何才能带package编译运行? JTable数据模型共享数据 请问使用西门子6688手机的朋友关于支持java: java程序的扩展名是什么?如何用jdk编译并生成一个可执行文件呢?我太菜了。各位大侠见笑了。 看有几个人能做出来~ java 如何将数据库获得的数据显示在jtable中
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;
}
}看生成的class文件内容: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: returnpublic 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: returnpublic static int get();
Code:
0: iconst_5
1: ireturn}看对应第一个循环最后的 20: goto 2,每次循环返回到标号2处,下面都要调用get()方法。
也就是说编译器没有进行优化。
因为表达式变量不能确定每次运算的结果是否相同,怎么可能为你优化呢?如果你写(long i = 0;i < System.currentTimeMillis();i++)
优化明显违反你的本意,而编译时优化并不能确定哪人表达式的值是固定的.
除非本身就是常量表达式.
第一种效率高是很明显的第二种每次进入for循环时都要计算Math.sqrt(n)的值勤
02
03 public static void main(String[] args) {
04 for (int i = 0; i < get(); i++) {
05 System.out.println("Hello world");
06 }
07 System.out.println("-----------");
08 for (int i = 0, k = get(); i < k; i++) {
09 System.out.println("test2");
10 }
11 }
12
13 public static int get() {
14 return 5;
15 }
16 }
不论是什么语言,不变的变量应该放在外面。
因为,在FOR循环中,通过调用函数来得到不变的变量需要消耗资源。