你相信java编译器对于循环的编译优化吗?

ktyl2000 2003-07-28 10:11:07
此文章只是用来在java编译器进行循环化方面的验证,本文是有感而发,并希望求得大家的分析结果,这里引用了一位网友的话(没有人身攻击的色彩):
///////////////////////////
对于Vector v=new Vector()若v中包含了10000个对象,我们进行一个loop如下
for(int I=0; I<v.size(); I++) { System.out.println("testing..."); }
大家一定会用如下的写法吧
int size = v.size(); for(int I=0; I<size; I++) { System.out.println("testing..."); }
///////////////////////////
但有些网友说(只是为了说明问题而已,无攻击色彩):
不能用完全解释语言过程来理解Java,v.size()在循环中并没有被调用10000次,因为,编译的循环优化会对其进行优化,
因此,实际运行时只运行一次,和用初始化v.size()的程序效率一样。这是很早的编译优化机制。

大家肯定这种说法正确吗?我不太赞同,很简单地可以用一个test作难证:
一个类Vector的类TetstObj.java

public class TestObj {
int count=0;
public TestObj() {
count+=5;
}
public int size(){
System.out.println("size="+count);
return count;
}
}

测试类:test.java

public class test{
public test(){}
public static void main(String[] args){
TestObj similarVector=new TestObj();
for(int i=1;i<similarVector.size();i++){
//do something
}
}
}

结果还是5个size=1的打印结果.
size=5
size=5
size=5
size=5
size=5
大家也可以分析一下java.util.Vector这个类(下面摘录Vector的部分源码)
例如只以一个insert对象而言:

/**
* Returns the number of components in this vector.
*
* @return the number of components in this vector.
*/
protected int elementCount;
/**
* Inserts the specified object as a component in this vector at the
* specified <code>index</code>. Each component in this vector with
* an index greater or equal to the specified <code>index</code> is
* shifted upward to have an index one greater than the value it had
* previously. <p>
*
* The index must be a value greater than or equal to <code>0</code>
* and less than or equal to the current size of the vector. (If the
* index is equal to the current size of the vector, the new element
* is appended to the Vector.)<p>
*
* This method is identical in functionality to the add(Object, int) method
* (which is part of the List interface). Note that the add method reverses
* the order of the parameters, to more closely match array usage.
*
* @param obj the component to insert.
* @param index where to insert the new component.
* @exception ArrayIndexOutOfBoundsException if the index was invalid.
* @see #size()
* @see #add(int, Object)
* @see List
*/
public synchronized void insertElementAt(Object obj, int index) {
modCount++;
if (index >= elementCount + 1) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
ensureCapacityHelper(elementCount + 1);
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
elementData[index] = obj;
elementCount++;
}
/**
* Returns the number of components in this vector.
*
* @return the number of components in this vector.
*/
public synchronized int size() {
return elementCount;
}

这象上面的similarVector对象一样,v.size()会每次调用Vector中的size()方法,10000次的调用一次也不会少吧!!
所以就我自身来说我不会相信java的对循环的编译优化,你呢??有何见解,请给出你的想法!大家也可以评论一些其它编译器的优化问题,
也给每位来读者一个好的回报!
...全文
84 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
ktyl2000 2003-07-28
  • 打赏
  • 举报
回复
to:Polarislee
你说的最有可能了,那些也正是不能看到的部分(编译器自身进行处理),也许它的编译原理是那样的(是不是可以看它的java specification才可以明白呀)
======================"Vector优化是不会出现的"这句最有可能了.

taolei 2003-07-28
  • 打赏
  • 举报
回复
Polariselee:
很遗憾,我测试了VJ的编译器和javac编译器,你举的两个例子没有你想象的那样。也就是说没有任何优化,跟不优化是一样的。

我查了JDK Document,在1.3版本中-O选项是不做任何事情的。
http://java.sun.com/j2se/1.3/docs/tooldocs/win32/javac.html
-O
Note: the -O option does nothing in the current implementation of javac and oldjavac.
Optimize code for execution time. Using the -O option may slow down compilation, produce larger class files, and make the program difficult to debug.
Prior to the Java 2 SDK, the -g and -O options of javac could not be used togther. As of the Java 2 SDK, v1.2, you can combine -g and -O, but you may get suprising results, such as missing variables or relocated or missing code. -O no longer automatically turns on -depend or turns off -g.


在1.4版本的doc中我就没有找到-O这个选项
http://java.sun.com/j2se/1.4/docs/tooldocs/win32/javac.html
北极猩猩 2003-07-28
  • 打赏
  • 举报
回复
对于Vector和ArrayList这种优化是无法进行的,因为其size地返回之可能在循环内部有所改变。比如,你在循环内向容器中插入新的对象。

这种循环优化是需要在计算的结果返回为常量的时候才会生效,比如:
for(int i=0; i<a.length; ++i)
{
//......
}

for(int i=0; i<t/10; ++i)
{
//循环中没有改变t的值
}

编译器可以检测出,你再循环中没有改变变量的值,但是没法检测出方法的返回知是否在循环过程中保持不变。所以,对Vector你所说的那种优化是不会出现的。
leejidongdong 2003-07-28
  • 打赏
  • 举报
回复
楼主的测试例子是不妥当的!
schwarzenegger 2003-07-28
  • 打赏
  • 举报
回复
Vector涉及到线程安全问题,也许java跳过有线程安全问题的优化

81,115

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧