簡體   English   中英

將函數內部的大變量聲明為`static`是否有任何性能差異?

[英]Is there any difference in performance to declare a large variable inside a function as `static`?

不確定之前是否已經提出這個問題。 在回答這個非常簡單的問題時 ,我問自己以下問題。 考慮一下:

void foo()
{
    int i{};
    const ReallyAnyType[] data = { item1, item2, item3,
        /* many items that may be potentially heavy to recreate, e.g. of class type */ };
    /* function code here... */
}

現在理論上,每次控制到達功能時都會重新創建局部變量,對吧? 即看上面的int i - 它肯定會在堆棧上重新創建。 上面的數組怎么樣? 編譯器可以像智能一樣優化其創建只發生一次,或者我還需要static修改器嗎? 如果數組不是const怎么辦? (好吧,如果它不是const ,那么在創建它時可能只有一次感覺,因為在函數執行期間進行修改時,可能需要在調用之間重新初始化為默認狀態。)

可能聽起來像一個基本問題,但出於某種原因,我仍然在思考。 另外,忽略“你為什么要這樣做” - 這只是一個語言問題,不適用於某個編程問題或設計。 我的意思是C和C ++。 如果這兩個問題存在差異,請概述這些問題。

我想這里有兩個問題:

  • 編譯器可以優化非static const對象進行有效static使得它不僅創造一次;

  • 給定的編譯器是否會這樣做是合理的期望。

我認為第二個問題的答案是“否”,因為我沒有看到進行大量控制流分析以保存程序員輸入單詞static的麻煩。 然而,我經常對人們花時間寫作的優化感到驚訝(與認為他們應該進行的優化相反:-))。 同樣,如果那就是你想要的,我強烈建議使用static這個詞。

對於第一個問題,在某些情況下,編譯器可以根據“as-if”規則執行優化,但在極少數情況下會解決。

首先,如果初始化程序中的任何對象或子對象具有非平凡的構造函數/析構函數,則構造/銷毀是可見的,這不是復制省略的示例。 (當然,這段只是C ++。)

如果初始化列表中的任何計算具有可見的副作用,則情況也是如此。

並且不言而喻,如果任何子對象的值不是常數,則需要在每個構造上完成該子對象的計算。

如果對象和所有子對象都是可以復制的,那么所有初始化列表計算都是常量,並且唯一的構造成本是從模板復制到對象中,如果有任何機會,編譯器仍然無法執行優化可以同時看到對象的多個實時實例的地址。 例如,如果函數是遞歸的,並且對象的地址在某處使用(難以避免數組),那么可能會比較來自函數的不同遞歸調用的這些對象中的兩個的地址。 他們必須比較不平等,因為它們實際上是單獨的對象。 (而且,現在我想起來了,這個函數甚至不需要在多線程環境中遞歸。)

因此,希望將該對象優化為單個靜態實例的編譯器的舉證責任非常高。 正如我所說的,很可能是給定的編譯器實際上嘗試執行該任務,但我絕對不會期望它。

編譯器幾乎肯定會做任何被認為是最優的東西,但很可能它會將它放在只讀內存中並將你的局部變量轉換為指向只讀內存中數組的指針。 這假設您的數組等同於POD類型(或由POD類型組成的類;如果您的類執行非常重要的操作和/或修改其他內容,則編譯器無法公平地執行此優化)。

暫無
暫無

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

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