簡體   English   中英

C ++:僅在未設置時設置bool值

[英]C++: Set bool value only if not set

我的C ++應用程序中的代碼通常會這樣做:

bool myFlag = false;
while (/*some finite condition unrelated to myFlag*/) {
    if (...) {
        // statements, unrelated to myFlag
    } else {
        // set myFlag to true, perhaps only if it was false before?
    }
}
if (myFlag) {
    // Do something...
}

我的問題與我的代碼的else語句有關。 基本上,我的循環可以根據某個未滿足的條件將myFlag的值從false設置為true。 永遠不會將旗幟從真假轉為虛假。 我想知道哪種語句在性能方面更有意義,並且可能由於編譯器優化而導致此問題實際上是非問題。

myFlag = true;

要么

if (!myFlag) myFlag = true;

我通常會選擇前者,因為它需要編寫更少的代碼。 然而,我開始懷疑它可能涉及不必要的寫入記憶,因此后者會阻止不必要的寫作,如果myFlag已經是真的。 但是,使用后者會花費更多時間,因為有一個條件語句,因此使用更多指令編譯代碼?

或許我過分思考這個......


更新1

只是澄清一下......后一種情況的目的是如果變量已經為真,則不寫入內存。 因此,只有在變量為false時才寫入內存。

你幾乎可以肯定只使用myFlag = true;

關於if (!myFlag) myFlag = true;的最好的希望if (!myFlag) myFlag = true; 是編譯器會注意到if是無關緊要的並且優化它。 特別是, if語句需要讀取 myFlag的當前值。 如果該值尚未存在於高速緩存中,則意味着在等待從存儲器讀取數據時指令將停止。

相比之下,如果您只是編寫(沒有先測試),則可以將值寫入寫入隊列,然后可以立即執行更多指令。 除非你讀取myFlag的值,否則你不會得到一個停頓(並且假設它在寫入后很快就會被讀取,它可能仍然在緩存中,所以拖延將是最小的)。

你確實意識到這個檢查沒有實際意義嗎? 如果您盲目地將其設置為true且未設置,則表示您正在設置它。 如果它已經是true ,那么沒有變化,你沒有 設置它,所以你有效地可以實現它:

myFlag = true;

關於潛在的優化,為了能夠測試,該值必須在緩存中 ,因此大部分成本已經支付。 另一方面,分支(如果編譯器沒有優化ifif大多數會這樣做)會對性能產生更大的影響。

CPU周期明智,更喜歡myFlag = true; 想一想:即使編譯器沒有進行優化(不太可能),只需設置它就需要一個asm語句,然后通過if需要至少1個asm語句。

所以請完成作業。

更重要的是,不要試圖對這種低級細節做出假設,特定的編譯器優化可能完全違背直覺。

你很可能像其他人已經提到的那樣過度思考問題,所以讓我也這樣做。 如果您能夠將與myFlag無關的語句加倍,則以下可能會更快。 事實上,你可以擺脫myFlag 好的,我們走了:

while (/*some finite condition*/) {
    if (...) {
        // statements
    } else {
        while (/*some finite condition*/) {
            if (...) {
               // statements, repeated
            }
        }
        // Do something (as if myFlag was true in the OPs example)
        break;
    }
}

與所有性能優化一樣:測量,測量,測量!

具體是架構是否if (!myFlag) myFlag = true; 比簡單的myFlag = true;需要更多的時間來執行myFlag = true; 即使沒有任何優化。 有一些體系結構(例如, https//developer.qualcomm.com/hexagon-processor ),其中兩個語句每個只執行一個循環。

了解您的機器的唯一方法是通過測量。

在任何情況下, myFlag = true將總是更快或具有相同的執行時間, if (!myFlag) myFlag = true;

這個問題也給我帶來了麻煩,所以我只是用以下代碼(C#)自己測試一下:

        System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
        int i = 0;
        int j = 1;

        time.Start();
        if (i != 0)
            i = 0;
        time.Stop();
        Console.WriteLine("compare + set - {0} ticks", time.ElapsedTicks);

        time.Reset();
        time.Start();
        if (j != 0)
            j = 0;
        time.Stop();
        Console.WriteLine("compare - {0} ticks", time.ElapsedTicks);


        time.Reset();
        time.Start();
        i = 0;
        time.Stop();
        Console.WriteLine("set - {0} ticks", time.ElapsedTicks);

        Console.ReadLine();

結果:

比較+設置 - 1個刻度

比較 - 1滴答

設置 - 0滴答

雖然用於設置值的時間肯定不為零,但它表明即使是單個查詢也需要比設置變量更多的時間。

暫無
暫無

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

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