簡體   English   中英

為什么分配方法返回值會使應用程序比調用它更快地運行?

[英]Why does to assign a method return makes application run faster than just calling it?

今天,當我發現意外情況時,我正在運行一些測試以更深入地了解程序中有哪些指令。 我運行以下測試來了解使用BigDecimal pow方法然后進行轉換(或者轉換為double並使用Math.pow)是否較慢。

public static void main(String[] args){

    BigDecimal myBd = new BigDecimal(2);

    Date start = new Date();
    System.out.println("inizio: " + start.toString());

    for(int i=0; i++<10000000;){
        Math.pow(myBd.doubleValue(),2); 
    }
    Date t1 = new Date();
    System.out.println("test 1 in:" +(t1.getTime() - start.getTime()));

    for(int i=0; i++<10000000;){
        myBd.pow(2);
    }
    Date t2 = new Date();
    System.out.println("test 2 in:" +(t2.getTime() - t1.getTime()));


    for(int i=0; i++<10000000;){
        double wtf = Math.pow(myBd.doubleValue(),2); 
    }
    Date t3 = new Date();
    System.out.println("test 3 in:" +(t3.getTime() - t2.getTime()));

    for(int i=0; i++<10000000;){
        double wtf = myBd.pow(2).doubleValue();
    }
    Date t4 = new Date();
    System.out.println("test 4 in:" +(t4.getTime() - t3.getTime()));

}

這是一個輸出示例:

測試1英寸:1268測試2英寸:1358測試3英寸:1049測試4英寸:1308

好的,我發現最好先轉換然后再使用Math pow,但是...等等,為什么地獄test1比test3慢,而test 2比test4慢?

越來越多地運行它總是相同的。 如果我指定返回值,則花費更少,然后只需調用該方法。

有人知道原因嗎?

以下是我的個人看法,如果我做錯了,請糾正我。 我不確定答案的准確性如何,我看到了問題的解決方法,現在我有了一些看法

BigDecimal的

BigDecimal.pow方法源代碼

private volatile BigInteger intVal;
.
.
.
public BigDecimal pow(int n) {
        if (n < 0 || n > 999999999) {
            throw new ArithmeticException("Invalid operation");
        }
        // No need to calculate pow(n) if result will over/underflow.
        // Don't attempt to support "supernormal" numbers.
        int newScale = checkScale((long) scale * n);
        this.inflate();
        return new BigDecimal(intVal.pow(n), newScale);
    }

觀察結果:

  • 每次調用pow方法都會創建一個BigDecimal對象
  • 主要計算通過intVal.pow(n) => BigInteger.pow完成(檢查上面BigDecimal pow代碼的返回語句)
  • 每個BigInteger.pow都會創建一個BigInteger.pow的新對象(已跳過BigInteger.pow的內部工作)

現在,BigDecimal EACH調用BigDecimal.pow的摘要創建了以下主要對象(其他計算似乎是次要的)

[在BigDecimal的Java源代碼實現中]

  • 兩個新的臨時BigInteger
  • 一個新的臨時BigDecimal

對於每個對pow的調用,我們創建了3個新的java.lang.Number(BigDecimal,BigInteger范圍編號)子類的臨時對象 ,這似乎是比較運行代碼所需時間的好地方

Math.pow

Math.pow方法源代碼

public static double pow(double a, double b) {
        return StrictMath.pow(a, b); // default impl. delegates to StrictMath
    }

這使用StrictMath的靜態方法pow,源代碼可以在此處找到,該鏈接代碼的第1511行很大,因此我沒有在此處粘貼。

觀察結果:

  • 使用Double類的靜態方法(我懷疑這將導致執行時間大大增加)
  • 使用了許多對基本類型的操作(這也需要較少的時間來運行)

我個人的看法/結論是

BigDecimal執行.pow方法時會創建許多對象,這可能是執行時間過長的原因

兩種方法的計算准確性超出了我的知識和經驗, 因此,請盡快嘗試探索准確性並更新此答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM