在我們編程的過程中經常會遇到這樣的問題。

for?(int?i=0;i<n;i++)
{
????String?str?=?//
}
String?str?=?null;

for(int?i=0;i<n;i++)
{
????str?=?//
}


在印象中一直認為方法二的性能好于方法一,但是差距應該很小。但因為一位別人的回文說方法一極大的影響了性能,所以想寫個例子證明一下相差很小。例子如下:

public?class?TestOt?
{

????public?static?void?main(String[]?args)?
{
????????long?n=1000000000;
????????long?start?=?System.currentTimeMillis();
????????test2(n);
????????long?end?=?System.currentTimeMillis();
????????System.out.println(end-start);
????}

????public?static?void?test1(long?n)
{

????????for?(int?i=0;i<n;i++)
{
????????????String?str?=?"";
????????}
????}

????public?static?void?test2(long?n)
{
????????String?str?=?null;

????????for?(int?i=0;i<n;i++)
{
????????????str?=?"";
????????}
????}
}測試的結果是當n=10億次的時候差距是1秒,所以說差距應該是很小的,符合我原始的記憶,但是另一個問題來了,測試的結果是
方法一:3300毫秒左右
方法二:4300毫秒左右
結果剛好相反,于是更改方法


public?class?TestOt?
{

????public?static?void?main(String[]?args)?
{
????????long?n=1000000000;
????????long?start?=?System.currentTimeMillis();
????????test1(n);
????????long?end?=?System.currentTimeMillis();
????????System.out.println(end-start);
????}

????public?static?void?test1(long?n)
{

????????for?(int?i=0;i<n;i++)
{
????????????String?str?=?null;
????????}
????}

????public?static?void?test2(long?n)
{
????????String?str?=?null;

????????for?(int?i=0;i<n;i++)
{
????????}
????}
}
結果依舊。
沒辦法,取得字節碼,對比

public?class?TestOt?extends?java.lang.Object
{
public?TestOt();
??Code:
???0:???aload_0
???1:???invokespecial???#8;?//Method?java/lang/Object."<init>":()V
???4:???return

public?static?void?test1(int);
??Code:
???0:???iconst_0
???1:???istore_1
???2:???goto????10???
???5:???aconst_null
???6:???astore_2
???7:???iinc????1,?1
???10:??iload_1???
???11:??iload_0
???12:??if_icmplt???????5
???15:??return

public?static?void?test2(int);
??Code:
???0:???aconst_null
???1:???astore_1
???2:???iconst_0
???3:???istore_2
???4:???goto????10???
???7:???iinc????2,?1
???10:??iload_2???
???11:??iload_0??
???12:??if_icmplt???????7
???15:??return
}
結果是感覺還是應該是方法二快,那為什么反而方法一快了1秒左右呢?
不得而知,現在我個人猜測的想法是可能有兩種情況:
1,JLS的底層定義決定的,有什么特殊的優化?
2,因為方法二比方法一雖然少了在循環中的部分,但是引用的聲明周期反而是更長了,是否因為引用存在造成了方法二的棧操作消耗了大部分時間?
猜想一有待于JLS文檔的查閱,我會在有空的時候查詢,猜想二正在想辦法證明。
看文章的朋友,如果誰了解麻煩指點一下,是我的測試方法寫的有問題,還是別的原因,謝謝。

文章來源:http://www.aygfsteel.com/dreamstone/archive/2007/02/11/99207.html















在印象中一直認為方法二的性能好于方法一,但是差距應該很小。但因為一位別人的回文說方法一極大的影響了性能,所以想寫個例子證明一下相差很小。例子如下:
































方法一:3300毫秒左右
方法二:4300毫秒左右
結果剛好相反,于是更改方法

































沒辦法,取得字節碼,對比



































結果是感覺還是應該是方法二快,那為什么反而方法一快了1秒左右呢?
不得而知,現在我個人猜測的想法是可能有兩種情況:
1,JLS的底層定義決定的,有什么特殊的優化?
2,因為方法二比方法一雖然少了在循環中的部分,但是引用的聲明周期反而是更長了,是否因為引用存在造成了方法二的棧操作消耗了大部分時間?
猜想一有待于JLS文檔的查閱,我會在有空的時候查詢,猜想二正在想辦法證明。
看文章的朋友,如果誰了解麻煩指點一下,是我的測試方法寫的有問題,還是別的原因,謝謝。
dreamstone 2007-02-11 03:26 發表評論
文章來源:http://www.aygfsteel.com/dreamstone/archive/2007/02/11/99207.html