[英]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已經是真的。 但是,使用后者會花費更多時間,因為有一個條件語句,因此使用更多指令編譯代碼?
或許我過分思考這個......
只是澄清一下......后一種情況的目的是如果變量已經為真,則不寫入內存。 因此,只有在變量為false時才寫入內存。
你幾乎可以肯定只使用myFlag = true;
。
關於if (!myFlag) myFlag = true;
的最好的希望if (!myFlag) myFlag = true;
是編譯器會注意到if
是無關緊要的並且優化它。 特別是, if
語句需要讀取 myFlag
的當前值。 如果該值尚未存在於高速緩存中,則意味着在等待從存儲器讀取數據時指令將停止。
相比之下,如果您只是編寫(沒有先測試),則可以將值寫入寫入隊列,然后可以立即執行更多指令。 除非你讀取myFlag的值,否則你不會得到一個停頓(並且假設它在寫入后很快就會被讀取,它可能仍然在緩存中,所以拖延將是最小的)。
你確實意識到這個檢查沒有實際意義嗎? 如果您盲目地將其設置為true
且未設置,則表示您正在設置它。 如果它已經是true
,那么沒有變化,你沒有 設置它,所以你有效地可以實現它:
myFlag = true;
關於潛在的優化,為了能夠測試,該值必須在緩存中 ,因此大部分成本已經支付。 另一方面,分支(如果編譯器沒有優化if
, if
大多數會這樣做)會對性能產生更大的影響。
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.