C 中 if 中 連線的判斷條件交換順序之後耗時增大一倍多,正常嗎?

時間 2021-05-31 03:42:09

1樓:Wang Shuai

所謂的常數優化很多時候其實是要養成的良好習慣。在每個細節的地方都能保持這些好習慣,系統大了你去profile優化瓶頸也會更有效,乙個處處都慢上一點點又沒有什麼特別集中的hot spot的程式優化起來就很頭疼了。

拿 @莫濤的程式為例:

23.2.4.

2] capacityReturns the number of elements in the %vectorsize_typesize() const _GLIBCXX_NOEXCEPTreturn size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }

10.64400c05: mov %r8,%rax

0.35400c08: add $0x1,%rbx

9.22400c0c: sub %rcx,%rax

0.35400c0f: sar $0x2,%rax

這個是for (int j = 0; j < e[x].size(); ++j) {

這一行對vector::size的呼叫(已經inline所以混入了乙個++j),所以每次迴圈都會load兩個pointer做一次減法再除4, 我們把它改成用iterator

for (auto iter = e[x].cbegin(); iter != e[x].cend(); ++iter) {

int y = *iter;

第五個測試點93ms

灰常簡單有木有!

BTW: 可以用兩個queue交替向另外的queue push可以省下那個h陣列,不過試了一下在這題上速度沒啥區別╮(╯▽╰)╭

2樓:Lawliet

太正常了,難道你不知道if裡面是進行惰性求值嗎?所以當一堆&&的時候,你盡量把最小概率為true的那個表示式放到最前面!

3樓:

你的問題不在於細節,而在於題本身,&&運算子是有執行順序的,左邊的條件表示式為真,才會判斷右邊的條件表示式!因此把耗時的判斷放在右邊才是正確的方式…

4樓:大餅哥

很遺憾,判定時間取決於執行時各個條件成真的概率。如果知道每個條件成真的概率,可以把概率最低的放在最前面,這樣可以執行時做最少的條件判定。

另外,兄弟,既然是C/C++,可以將迴圈內下標的方式換成指標試試速度有沒有提公升。

5樓:橙子

其實位操作的&和邏輯運算子&&都可以拿來判斷左右兩邊結果,這兩個的區別是:

&操作,即使左邊結果是0,右邊的判斷它還是會去計算。

&&操作,如果左邊結果是0,那麼右邊就不會執行了。

按題主的情況來看,左右互換之前,排左邊的結果為0的情況比較多,那麼比較耗時的右邊兩項判斷就不會執行。

入門程式設計師的粗鄙答案,如有不妥之處,請指出斧正。

6樓:

因為 cache not hit, reload and replace, cache not hit, reload and replace, ...

7樓:

其實這個損耗是很正常的…這裡調換if裡的判斷順序就是我們說的常數優化(讓時間複雜度前面的常數小一些)更為常見的是讀入優化,手動佇列等…

C 中解除cin和cout連線是否有必要tie兩次?

大明醬 關於std tie,可見 可以看到其定義 ostream tie const get ostream tie ostream tiestr set 可見其set引數為輸出流。那麼std cin tie nullptr 即為把cin 輸入流 和nullptr 空輸出流 繫結,即解除鏈結。而st...

c 中能否判斷乙個指標指向棧還是堆?

Rico 如果假定指標非堆即棧,不考慮 code bss mmap 這些段位址的話,應該是可以的。提供乙個思路 1 讀取暫存器狀態 2 通過 rbp ebp 回溯堆疊,找到頂級堆疊的 ebp,也就是整個程序 執行緒 的堆疊起始位址 3 使用指標位址與堆疊起始位址比較,差值與平台相關的最大堆疊size...

C 中的類 class entry public entry next 這裡的entry與next有什麼關係?entry怎麼能修飾next呢?

你建立了乙個類,就建立了乙個型別。public entry next 看不懂,public Integer next 能看懂吧?乙個道理。 南蔥 遞迴型別並不是乙個很基礎的概念,乙個型別之所以能成為它自己的組成部分,乙個很重要的前提就是遞迴型別展開是可以終止的,換句話說就是該型別的例項可以為空值 這...