簡體   English   中英

我怎樣才能確定一個例程正在利用(N)RVO?

[英]How can I be sure a routine is taking advantage of (N)RVO?

我想確保我的例程盡可能利用(N)RVO。 除了解析生成的反匯編之外,還有什么我可以做或檢查是否正在使用(N)RVO編譯例程? 在這一點上,我最感興趣的是MSVC和GCC。

不,不是真的。

但是,您可以在編寫代碼時遵循指南。


未命名的返回值優化

即使在調試模式下,每次返回臨時值時都會觸發此操作。

return MyObject(....);

命名返回值優化

每次函數總是返回相同的臨時對象時,這幾乎都會觸發:

MyObject func() {
  MyObject result;
  if (...) { return result; }

  result.push(0);
  return result;
}

您可以混合使用這些,但在這種情況下編譯器幾乎不可能應用RVO:

MyObject func() {
  MyObject result;
  if (...) { return MyObject(...); }

  return result;
}

在這里,一個回報可能會受益於RVO而另一個則不受益。 我敢打賭第一個被優化,因為如果你推測性地在返回槽中創建result並且突然需要采用if分支,你就會陷入困境。 請注意,只需重新排序語句就可以了:

MyObject func() {
  if (...) { return MyObject(...); }

  MyObject result;

  return result;
}

因此,NRVO的經驗法則是, result聲明與return result;之間不應有return聲明return result; 返回result本身以外的任何其他語句。


如果你遵循這個,你可以為你贏得賠率。 然后,這只是代碼審查的問題。

並且您還可以使代碼更易於閱讀,因為在知道您確實需要它們之前不會聲明變量!

您可以向析構函數添加調試方法:

struct A
{
   ~A() { cout << "destructor called"; }
};

A foo()
{
   A a;
   return a;
}

如果調用析構函數,則可能未應用RVO。

我能想到的可能方法是:

  1. 在類中實現引用計數機制,跟蹤通過類創建的實例數,類似於shared_ptr ,這樣就可以檢測正在創建的類的額外副本,如果沒有發生復制省略則刪除。

  2. 您可以簡單地將調試跟蹤放在類的復制構造函數和析構函數中,如果沒有發生復制省略,您會看到許多連續的復制構造函數和析構函數調試跟蹤。

暫無
暫無

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

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