我看Java 5.0的编译选项里面没有-O,我不知道Java编译器会不会自动把函数“内联”
如果有以下的代码
class C {
int a;
public int geta() {
return a;
}
}如果使用
C c=new C();
int b=c.a 与 int b=c.geta() 速度会一样吗?
如果有以下的代码
class C {
int a;
public int geta() {
return a;
}
}如果使用
C c=new C();
int b=c.a 与 int b=c.geta() 速度会一样吗?
解决方案 »
- 关于HASHCODE与equals的疑惑。
- 请教一个关于JAVA静态对象存储区域的问题!!!!!
- 请教一个截取字段的问题
- 如何固定jface中的Table组件的checkbox?
- java能支持播放什么格式的音频文件
- 如何获得arraylist的长度,之后从其中去除一个元素呢?
- 在if(e.getSource().equals(fuButton1))方法里面哪个地方出了错,请帮我改改,它错在那里呢?谢谢!
- Applet怎样访问数据库?Applet中如何实现拖曳操作??
- Jbuilder里面如何增加JDBC驱动
- 循环里面应该避免数据库操作吗
- 我的JCreator Pro在编译的时候,出现了一个这种错误!
- 请问qq中给绑定手机发短信是如何实现的?
原来代码:
class C{
int a;
public int geta() {
return a;
}
public static void main(String[] args) {
C c = new C();
int b = c.a;
int bb = c.geta();
System.out.println("b = " + b);
System.out.println("bb = " + bb);
}
}
===========编译后再反编译import java.io.PrintStream;class C
{ C()
{
} public int geta()
{
return a;
} public static void main(String args[])
{
C c = new C();
int i = c.a;
int j = c.geta();
System.out.println((new StringBuilder()).append("b = ").append(i).toString());
System.out.println((new StringBuilder()).append("bb = ").append(j).toString());
} int a;
}
开始我也这样想,但刚才试了试觉得比较奇怪:
===========final class
import java.io.PrintStream;final class C
{ C()
{
} public int geta()
{
return a;
} public static void main(String args[])
{
C c = new C();
int i = c.a;
int j = c.geta();
System.out.println((new StringBuilder()).append("b = ").append(i).toString());
System.out.println((new StringBuilder()).append("bb = ").append(j).toString());
} int a;
}
================final method
import java.io.PrintStream;class C
{ C()
{
} public final int geta()
{
return a;
} public static void main(String args[])
{
C c = new C();
int i = c.a;
int j = c.geta();
System.out.println((new StringBuilder()).append("b = ").append(i).toString());
System.out.println((new StringBuilder()).append("bb = ").append(j).toString());
} int a;
}
========
无加任何编译参数,就javac C.java
赞成kingfish(八百里秦川@龙城异客)。J2ME里就是建议用
int b=c.a
我认为是
因为c.a是类内的变量,new时就在堆上了。
所以int b = c.a就直接复制或者是指向c.a所对应的常量(这个有编译器决定吧,我猜的:))。int b=c.geta()
而这个(你想)先是一个函数调用(分配一个栈空间),
再返回给b(就直接复制或者是指向c.a所对应的常量),
然后释放栈
三步。恩,就是这样所以是b = c.a快。
:P
{
public static void main(String[] args) {
hello h = new hello();
final long max=99999999l;
long t[]=new long[4];
t[0]=System.currentTimeMillis();
for(long i=0;i<max;i++)
p(h.s);
t[1]=System.currentTimeMillis(); for(long i=0;i<max;i++)
p(h.getHello());
t[2]=System.currentTimeMillis(); System.out.println("time(1-0):" + (t[1]-t[0]));
System.out.println("time(2-1):" + (t[2]-t[1]));
}
public static void p(String s){
//System.out.println("Hello World!");
} public String s="hello";
public String getHello(){
return s;
}
}================================
max=9999999l;
---------- 运行 ----------
time(1-0):469
time(2-1):438=============================
max=999999l
---------- 运行 ----------
time(1-0):47
time(2-1):47
Normal Termination=============================
max=999999l
---------- 运行 ----------
time(1-0):47
time(2-1):47
=============================
其他情况都是不定的.jdk1.50
J2ME里就是建议用
int b=c.a
用这样的方法好像就有违于封装的初衷了。C++中我一直都用getXXX加上inline的。到了Java没想到却要在速度与封装性之间进行取舍了。
这里是说类直接变量访问和用setter或getter访问的速度问题。
J2ME是在受限设备里运行,最后要进一步提高运行效率推荐使用。
我认为封装在一定程度上可以有程序员自己界定,不过那有些难。
javac 进行的优化很少的,就现在使用的 JDK 来说,好像 javac 只对"死代码"和"提前计算"进行优化,
这也是为什么现在 javac 没有 -o 优化编译选项的原因.至于你说的象"内联"等对运行时间的优化,现在已经完全不用编译时进行优化了.
这些全部由 java 运行时的 JIT 编译器进行的.就像你提出的代码,如果是在一个循环里调用, JIT 肯定是会编译成内联代码的,这些不用你去担心,编写 JRE 的专家早就处理好了.