10

より効率的な C++ コードを記述できるようにする C++0x の改善点の 1 つは、unique_ptr スマート ポインターです (残念ながら、memmove() のような操作を介して移動することはできません: 提案はドラフトに含まれていませんでした)。

今後の標準でのその他のパフォーマンスの改善点は何ですか? 次のコードを例にとります。

vector<char *> v(10,"astring");
string concat = accumulate(v.begin(),v.end(), string(""));

このコードは、ベクトルvに含まれるすべての文字列を連結します。このきちんとしたコードの問題は、accumulate() がコピーを行い、参照を使用しないことです。また、プラス演算子が呼び出されるたびに string() が再割り当てされます。したがって、このコードは、適切に最適化された類似の C コードに比べてパフォーマンスが低下します。

C++0x は問題を解決するためのツールを提供していますか?

4

4 に答える 4

14

はい、C++ はムーブ セマンティクスと呼ばれるものを通じて問題を解決します。

基本的に、オブジェクトが一時的なものである場合、あるオブジェクトが別のオブジェクトの内部表現を引き継ぐことができます。たとえば、コピー コンストラクターを使用して文字列内のすべてのバイトをコピーする代わりに、多くの場合、宛先文字列がソース文字列の内部表現を引き継ぐようにすることができます。これは、ソースが右辺値の場合にのみ許可されます。

これは、ムーブ コンストラクターの導入によって行われます。src オブジェクトが一時的なものであり、なくなることがわかっているコンストラクターです。したがって、宛先が src オブジェクトの内部表現を取ることは許容されます。

移動代入演算子についても同様です。

コピー コンストラクターとムーブ コンストラクターを区別するために、言語には右辺値参照が導入されています。クラスは、右辺値(一時) にのみバインドされる右辺値参照を取るように移動コンストラクターを定義します。したがって、私のクラスは次の行に沿って何かを定義します。

 class CMyString
 {
 private:
     char* rawStr;
 public:

     // move constructor bound to rvalues
     CMyString(CMyString&& srcStr) 
     {
         rawStr = srcStr.rawStr
         srcStr.rawStr = NULL;             
     }

     // move assignment operator 
     CMyString& operator=(CMyString&& srcStr) 
     {
         if(rawStr != srcStr.rawStr) // protect against self assignment
         {
             delete[] rawStr;
             rawStr = srcStr.rawStr
             srcStr.rawStr = NULL;
         }
         return *this;
     }

     ~CMyString()
     {
         delete [] rawStr;
     }
 }

これは、移動のセマンティクスとこれを可能にする構文に関する非常に優れた詳細な記事です。

于 2009-06-10T13:01:48.497 に答える
7

1 つのパフォーマンス向上は、キーワード constexpr によって導入される一般化された定数式です。

constexpr int returnSomething() {return 40;}

int avalue[returnSomething() + 2]; 

returnSomething()+2 は定数式ではないため、これは正当な C++ コードではありません。

ただし、constexpr キーワードを使用することで、C++0x は、式がコンパイル時の定数であることをコンパイラに伝えることができます。

于 2009-06-10T13:04:56.010 に答える
1

申し訳ありませんが、再割り当てがstring concat = accumulate(v.begin(),v.end(), string("")); 必要であるとは言えません。もちろん、単純な実装でも問題ありません。しかし、コンパイラはここで正しいことを行うことが非常に許可されています。

これは C++98 ではすでに当てはまり、C++0x では引き続きスマート実装とダム実装の両方が許可されます。そうは言っても、移動セマンティクスはスマートな実装をより簡単にします。

于 2009-06-10T14:32:48.017 に答える