SlideShare a Scribd company logo
Item 41. Consider pass by value for copyable
parameters that are cheap to move and always copied.
Mitsutaka Takeda
September 30, 2015
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 1 / 25
Outline
...1 Chapter 8. Tweaks
...2 Item 41: Consider pass by value for copyable parameters that are cheap to
move and always copied.
...3 おまけ & 参考情報
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 2 / 25
Chapter 8. Tweaks
Introduction
適切な場面と適切ではない場面の判断が難しい 2 つのテクニックを紹介。
判断が難しいので"consider"。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 3 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
parameters that are always copied
(メンバ) 関数の定義内で copy が必要なパラメータ (setter などメンバ変数への保
持) は、性能を考慮すると、lvalue は copy、rvalue は move するべき。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 4 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
1st take (Overloads for lvalue and rvalue)
class Widget {
public:
void addName(const std::string& newName) {
// lvalueを取って、メンバ変数namesにcopy
names.push_back(newName);
}
void addName(std::string&& newName) {
// rvalueを取って、メンバ変数namesにmove。
names.push_back(std::move(newName));
}
private:
std::vector<std::string> names;
};
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 5 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
1st take (overloads for lvalue and rvalue) の問題点
" 名前を追加する"(addName) という同じコンセプトに対して、lvalue 用と
rvalue 用の 2 つの実装がある。ソース・コード量が 2 倍 => メンテナンス・コス
トが増える。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 6 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
2nd take (Universal reference)
class Widget {
public:
template <typename T>
void addName(T&& newName){
// Universal reference && Perfect forwarding.
names.push_back(std::forward<T>(newName));
}
private:
std::vector<std::string> names;
};
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 7 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
2nd take (Universal reference) の特徴
ソース・コード量は Overloads の半分。template のインスタンス化 (lvalue、
rvalue、std::string、const char*) が原因でオブジェクトのサイズは大きくなるか
も。
ヘッダ・ファイルに実装しなければいけない。
Item 30 で説明したように Universal Reference で渡せない引数がある
(initilizer list 等)。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 8 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
3rd take (Pass by value)
class Widget {
public:
void addName(std::string newName) {
// 引数がlvalueでもrvalueでもmove。
// newNameはcopyされたオブジェクトなのでmoveしても問題無い。
names.push_back(std::move(newName));
}
private:
std::vector<std::string> names;
};
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 9 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
3rd take (Pass by value) の特徴
lvalue に対して addName が呼ばれた場合は lvalue が copy される。
rvalue に対して addName が呼ばれた場合は rvalue が move される。
Overloads に対してソース・コードの量が半分。
Universal reference のような問題点がない (実装の詳細漏れ、オブジェクト・サ
イズの肥大化、理解しづらいコンパイル・エラー)
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 10 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
性能 (copy & move constructor 回数) の比較
lvalue rvalue
Overloads 1 copy into names 1 move into names
Universal 1 copy into names 1 move into names
By value 1 copy into newName 1 move into newName
1 move into names 1 move into names
newName は関数 Widget::addName のパラメータ。
names は Widget のメンバ変数 (std::vector<std::string>)。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 11 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
Back to the title
Consider pass by value for copyable parameters that are cheap to move
and always copied.
回りくどい言い方をしている 4 つの理由。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 12 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
1st reason
Consider pass by value for copyable parameters that are cheap to move
and always copied.
ソース・コードの量も少く、オブジェクト・コードのサイズも小さく、Universal reference
の問題点も無いが、Overloads や Universal reference と比較して性能面のコストが
1 move 分大きい (move 以外のコストについては以下で議論)。
"Consider" = 選択肢の 1 つに含める。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 13 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
2nd reason
Consider pass by value for copyable parameters that are cheap to move
and always copied.
パラメータが copyable で無い場合、copy する (オジェクトの所有権を caller から
callee に渡す) には move するしか方法が無い。
class Widget {
public:
// ptrの所有権をWidgetに移すにはmoveするしかない。
// const lvalue referenceはコンパイル・エラー。
// rvalue referenceの関数だけ定義すれば良い。
void setPtr(std::unique_ptr<std::string>&& ptr){
p = std::move(ptr);
}
private:
std::unique_ptr<std::string> p;
};
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 14 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
3rd reason
Consider pass by value for copyable parameters that are cheap to move
and always copied.
Pass by value は Overloads や Universal reference と比較して、1 move 分処理が多
い。std::array のように move と copy のコストが同じような場合はこの余計な move
が問題になる。
lvalue rvalue
Overloads 1 copy into names 1 move into names
Universal 1 copy into names 1 move into names
By value 1 copy into newName 1 move into newName
1 move into names 1 move into names
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 15 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
4th reason
Consider pass by value for copyable parameters that are cheap to move
and always copied.
渡したパラメータが copy されない場合があるとき、copy 不要なシーケンスでは、
Overloads や Universal reference と比較して 1 copy 分処理が多くなる。
class Widget {
public:
void addName(std::string newName) {
// By ValueではnewNameに渡された時点でcopyが発生する。
// namesにnewNameをpush_backしない場合は、OverloadsやUniversal ref
// ではcopyは発生しない。
if(newName.length() >= minLen && newName.length() <= maxLen) {
names.push_back(std::move(newName));
}
}
private:
std::vector<std::string> names;
};
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 16 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
constructor & assignment Part 1
"copyable && cheap-to-move && always copied" でも Pass by value が相応しくな
い場合。
オブジェクトのコピーがコンストラクタではなく代入で行なわれる場合。コンストラク
タは新しいオブジェクトを構築するための操作なのに対して、代入は構築済みのオ
ブジェクトに対する操作。代入では構築済みオブジェクトのリソースを再利用する
チャンスがある。
std::vector<T>::push_back は T のコンストラクタが実行される。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 17 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
constructor & assignment Part 2
Pass by value での changeTo のコスト。newPwd の copy construction でメモリ確
保と move assignemnt での text のメモリ解放。
class Password {
public:
explicit Password(std::string pwd)
: text(std::move(pwd))
{}
void changeTo(std::string newPwd){ // copy construction
text = std::move(newPwd); // move assignment
}
private:
std::string text;
};
int main()
{
std::string initPwd("Supercalifragilisticexpialidocious");
Password p(initPwd);
std::string newPassword("Beware the Jabberwock");
p.changeTo(newPassword);
return 0;
}
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 18 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
constructor & assignment Part 3
Overloads のコスト。newPwd の copy construction でメモリ確保 const lvalue
reference への束縛、move assignemnt での text のメモリ解放 copy assignment で
text のメモリ領域の再利用 (文字列をコピー)。copy 前に text に保存されていた文
字列 (initPwd) が新しい文字列 newPassword より長いため。
class Password {
public:
explicit Password(std::string pwd)
: text(std::move(pwd))
{}
void changeTo(const std::string& newPwd){ // bind to const lvalue reference
text = newPwd; // copy assignment
}
private:
std::string text;
};
int main() {
std::string initPwd("Supercalifragilisticexpialidocious");
Password p(initPwd);
std::string newPassword("Beware the Jabberwock"); // call newpassWord with lvalue.
p.changeTo(newPassword);
return 0;
}
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 19 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
cost of assignment
call with lvalue
text’s resouce is reusable text’s resource is not reusable
Overloads 0 allocation & 0 deallocation 1 allocation & 1 deallocation
both in copy asgnmt
Universal 0 allocation & 0 deallocation 1 allocation & 1 deallocation
both in copy asgnmt
By value 1 allocation in copy ctor 1 allocation in copy ctor
& 1 deallocation in move asgnmt 1 deallocation in move asgnmt
call with rvalue
text’s resouce is reusable text’s resource is not reusable
Overloads 0 allocation & 1 deallocation 1 allocation & 1 deallocation
Universal 0 allocation & 1 deallocation 1 allocation & 1 deallocation
By value 0 allocation & 1 deallocation 1 allocation & 1 deallocation
reusable : text.size() >= newPassword.size()
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 20 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
penalty of pass by value with assignment と IF を選択する
さいのアドバイス
.
Penalty を決定する要因
..
......
パラメータの型 (リソースの取得と解放)
関数の呼ばれ方 (lvalue or rvalue)
assignment operator の実装 (リソースの再利用)
.
推定有罪 for Pass by value
..
......
assignment を使用してコピーしている場合、Pass by value を使用しても性能的に問
題ないと確認できるまで、Overloads/Universal reference を使用する。
.
性能を追求するソフトウェアでは Pass by value は使用しない
..
......
move1 回のコストは低くても、塵も積れば。
std::string f(std::string);// pass by value
std::string g(std::string);// pass by value
std::string h(std::string);// pass by value
auto result = h(g(f(std::string("abc")))); // 4 moves
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 21 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
Performance 以外の問題 (Slicing)
関数が引数を多相的に扱いたい場合、パラメータはポインタ、または、参照でなけれ
ばいけない。
class Widget{};
class SpecialWidget : public Widget {};
// processWidgetはWidgetのサブ・タイプに対しても適用できる関数。
void processWidget(Widget w);// Pass by value
SpecialWidget sw;
// slicing。processWidgetはswをWidget型として扱う。
processWidget(sw);
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 22 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
Review
copyable & cheap-to-move & always copied なら、pass by value を使用すると、
実装が単純で、オブジェクト・コードのサイズが小さく、効率的なコードになる か
もしれない 。
assingment より constructor の方がコストが高いときがある (リソースの再利
用)。
Slicing 問題があるので多相的にオブジェクトを使用したいときは pass by value
は使用できない。
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 23 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
実際?
.
Overloads は組合せの爆発。
..
......
// 2引数に対して4 overloads。
void f(std::string v0, std::string v1);
void f(const std::string& v0, const std::string& v1);
void f(std::string&& v0, const std::string& v1);
void f(std::string&& v0, std::string&& v1);
.
Universal reference はヘッダ依存 & コンパイル時間の増加。
........
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 24 / 25
Item 41: Consider pass by value for copyable parameters that are cheap to move
and always copied.
Pass by value for constructor
Constructor で渡すパラメータはコピーされる。(メンバ変数の初期化で使用)
メンバ変数の初期化は copy constructor で行なわれる。(初期化リスト)
気にしなければいけないのは copyable かどうかと cheap-to-move だけ。
class MyClass {
public:
MyClass(std::string v0,
std::string v1)
: v0_(std::move(v0)),
v1_(std::move(v1))
{}
private:
std::string v0_;
std::string v1_;
};
Back to Basics! Essentials of Modern C++ Style@CPPCOn 2014 by Herb Sutter
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 25 / 25
おまけ & 参考情報
.
The evolving search for effective C++ - Keynote@Meeting C++ 2014 by Scott
Meyers
..
......
Movie
Slides
.
Back to Basics! Essentials of Modern C++ Style@CPPCOn 2014 by Herb Sutter
..
......
Movie
Slides
Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 25 / 25

More Related Content

What's hot

Agda による型推論器の定式化
Agda による型推論器の定式化Agda による型推論器の定式化
Agda による型推論器の定式化
Kyoko Kadowaki
 
Emcjp item21
Emcjp item21Emcjp item21
Emcjp item21
MITSUNARI Shigeo
 
PPL2016-9-3
PPL2016-9-3PPL2016-9-3
PPL2016-9-3
Kyoko Kadowaki
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!
Akihiro Nishimura
 
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
Takashi Hoshino
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
TATSUYA HAYAMIZU
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
啓 小笠原
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
信之 岩永
 
Final LINQ Extensions
Final LINQ ExtensionsFinal LINQ Extensions
Final LINQ Extensions
Kouji Matsui
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
Kohsuke Yuasa
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
Hibiki Yamashiro
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Shintarou Okada
 
C++ tips4 cv修飾編
C++ tips4 cv修飾編C++ tips4 cv修飾編
C++ tips4 cv修飾編
道化師 堂華
 
error handling using expected
error handling using expectederror handling using expected
error handling using expected
Akira Takahashi
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会Akihiko Matuura
 

What's hot (20)

Agda による型推論器の定式化
Agda による型推論器の定式化Agda による型推論器の定式化
Agda による型推論器の定式化
 
Emcjp item21
Emcjp item21Emcjp item21
Emcjp item21
 
PPL2016-9-3
PPL2016-9-3PPL2016-9-3
PPL2016-9-3
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!
 
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
 
Final LINQ Extensions
Final LINQ ExtensionsFinal LINQ Extensions
Final LINQ Extensions
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
Map
MapMap
Map
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
 
What is template
What is templateWhat is template
What is template
 
C++ tips4 cv修飾編
C++ tips4 cv修飾編C++ tips4 cv修飾編
C++ tips4 cv修飾編
 
error handling using expected
error handling using expectederror handling using expected
error handling using expected
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
 

Similar to Emcpp item41

po-2. Python プログラミングの基本
po-2. Python プログラミングの基本po-2. Python プログラミングの基本
po-2. Python プログラミングの基本
kunihikokaneko1
 
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Yusuke Uchida
 
点群SegmentationのためのTransformerサーベイ
点群SegmentationのためのTransformerサーベイ点群SegmentationのためのTransformerサーベイ
点群SegmentationのためのTransformerサーベイ
Takuya Minagawa
 
CppCV03
CppCV03CppCV03
Chainerの使い方と 自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と 自然言語処理への応用
Yuya Unno
 
Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)
Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)
Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)
Shinya Takamaeda-Y
 
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7Tetsuya Morimoto
 
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
Hiroshi Watanabe
 

Similar to Emcpp item41 (8)

po-2. Python プログラミングの基本
po-2. Python プログラミングの基本po-2. Python プログラミングの基本
po-2. Python プログラミングの基本
 
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
 
点群SegmentationのためのTransformerサーベイ
点群SegmentationのためのTransformerサーベイ点群SegmentationのためのTransformerサーベイ
点群SegmentationのためのTransformerサーベイ
 
CppCV03
CppCV03CppCV03
CppCV03
 
Chainerの使い方と 自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と 自然言語処理への応用
 
Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)
Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)
Veriloggen: Pythonによるハードウェアメタプログラミング(第3回 高位合成友の会 @ドワンゴ)
 
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7
 
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
 

Emcpp item41

  • 1. Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied. Mitsutaka Takeda September 30, 2015 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 1 / 25
  • 2. Outline ...1 Chapter 8. Tweaks ...2 Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. ...3 おまけ & 参考情報 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 2 / 25
  • 3. Chapter 8. Tweaks Introduction 適切な場面と適切ではない場面の判断が難しい 2 つのテクニックを紹介。 判断が難しいので"consider"。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 3 / 25
  • 4. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. parameters that are always copied (メンバ) 関数の定義内で copy が必要なパラメータ (setter などメンバ変数への保 持) は、性能を考慮すると、lvalue は copy、rvalue は move するべき。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 4 / 25
  • 5. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 1st take (Overloads for lvalue and rvalue) class Widget { public: void addName(const std::string& newName) { // lvalueを取って、メンバ変数namesにcopy names.push_back(newName); } void addName(std::string&& newName) { // rvalueを取って、メンバ変数namesにmove。 names.push_back(std::move(newName)); } private: std::vector<std::string> names; }; Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 5 / 25
  • 6. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 1st take (overloads for lvalue and rvalue) の問題点 " 名前を追加する"(addName) という同じコンセプトに対して、lvalue 用と rvalue 用の 2 つの実装がある。ソース・コード量が 2 倍 => メンテナンス・コス トが増える。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 6 / 25
  • 7. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 2nd take (Universal reference) class Widget { public: template <typename T> void addName(T&& newName){ // Universal reference && Perfect forwarding. names.push_back(std::forward<T>(newName)); } private: std::vector<std::string> names; }; Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 7 / 25
  • 8. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 2nd take (Universal reference) の特徴 ソース・コード量は Overloads の半分。template のインスタンス化 (lvalue、 rvalue、std::string、const char*) が原因でオブジェクトのサイズは大きくなるか も。 ヘッダ・ファイルに実装しなければいけない。 Item 30 で説明したように Universal Reference で渡せない引数がある (initilizer list 等)。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 8 / 25
  • 9. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 3rd take (Pass by value) class Widget { public: void addName(std::string newName) { // 引数がlvalueでもrvalueでもmove。 // newNameはcopyされたオブジェクトなのでmoveしても問題無い。 names.push_back(std::move(newName)); } private: std::vector<std::string> names; }; Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 9 / 25
  • 10. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 3rd take (Pass by value) の特徴 lvalue に対して addName が呼ばれた場合は lvalue が copy される。 rvalue に対して addName が呼ばれた場合は rvalue が move される。 Overloads に対してソース・コードの量が半分。 Universal reference のような問題点がない (実装の詳細漏れ、オブジェクト・サ イズの肥大化、理解しづらいコンパイル・エラー) Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 10 / 25
  • 11. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 性能 (copy & move constructor 回数) の比較 lvalue rvalue Overloads 1 copy into names 1 move into names Universal 1 copy into names 1 move into names By value 1 copy into newName 1 move into newName 1 move into names 1 move into names newName は関数 Widget::addName のパラメータ。 names は Widget のメンバ変数 (std::vector<std::string>)。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 11 / 25
  • 12. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. Back to the title Consider pass by value for copyable parameters that are cheap to move and always copied. 回りくどい言い方をしている 4 つの理由。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 12 / 25
  • 13. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 1st reason Consider pass by value for copyable parameters that are cheap to move and always copied. ソース・コードの量も少く、オブジェクト・コードのサイズも小さく、Universal reference の問題点も無いが、Overloads や Universal reference と比較して性能面のコストが 1 move 分大きい (move 以外のコストについては以下で議論)。 "Consider" = 選択肢の 1 つに含める。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 13 / 25
  • 14. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 2nd reason Consider pass by value for copyable parameters that are cheap to move and always copied. パラメータが copyable で無い場合、copy する (オジェクトの所有権を caller から callee に渡す) には move するしか方法が無い。 class Widget { public: // ptrの所有権をWidgetに移すにはmoveするしかない。 // const lvalue referenceはコンパイル・エラー。 // rvalue referenceの関数だけ定義すれば良い。 void setPtr(std::unique_ptr<std::string>&& ptr){ p = std::move(ptr); } private: std::unique_ptr<std::string> p; }; Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 14 / 25
  • 15. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 3rd reason Consider pass by value for copyable parameters that are cheap to move and always copied. Pass by value は Overloads や Universal reference と比較して、1 move 分処理が多 い。std::array のように move と copy のコストが同じような場合はこの余計な move が問題になる。 lvalue rvalue Overloads 1 copy into names 1 move into names Universal 1 copy into names 1 move into names By value 1 copy into newName 1 move into newName 1 move into names 1 move into names Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 15 / 25
  • 16. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 4th reason Consider pass by value for copyable parameters that are cheap to move and always copied. 渡したパラメータが copy されない場合があるとき、copy 不要なシーケンスでは、 Overloads や Universal reference と比較して 1 copy 分処理が多くなる。 class Widget { public: void addName(std::string newName) { // By ValueではnewNameに渡された時点でcopyが発生する。 // namesにnewNameをpush_backしない場合は、OverloadsやUniversal ref // ではcopyは発生しない。 if(newName.length() >= minLen && newName.length() <= maxLen) { names.push_back(std::move(newName)); } } private: std::vector<std::string> names; }; Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 16 / 25
  • 17. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. constructor & assignment Part 1 "copyable && cheap-to-move && always copied" でも Pass by value が相応しくな い場合。 オブジェクトのコピーがコンストラクタではなく代入で行なわれる場合。コンストラク タは新しいオブジェクトを構築するための操作なのに対して、代入は構築済みのオ ブジェクトに対する操作。代入では構築済みオブジェクトのリソースを再利用する チャンスがある。 std::vector<T>::push_back は T のコンストラクタが実行される。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 17 / 25
  • 18. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. constructor & assignment Part 2 Pass by value での changeTo のコスト。newPwd の copy construction でメモリ確 保と move assignemnt での text のメモリ解放。 class Password { public: explicit Password(std::string pwd) : text(std::move(pwd)) {} void changeTo(std::string newPwd){ // copy construction text = std::move(newPwd); // move assignment } private: std::string text; }; int main() { std::string initPwd("Supercalifragilisticexpialidocious"); Password p(initPwd); std::string newPassword("Beware the Jabberwock"); p.changeTo(newPassword); return 0; } Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 18 / 25
  • 19. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. constructor & assignment Part 3 Overloads のコスト。newPwd の copy construction でメモリ確保 const lvalue reference への束縛、move assignemnt での text のメモリ解放 copy assignment で text のメモリ領域の再利用 (文字列をコピー)。copy 前に text に保存されていた文 字列 (initPwd) が新しい文字列 newPassword より長いため。 class Password { public: explicit Password(std::string pwd) : text(std::move(pwd)) {} void changeTo(const std::string& newPwd){ // bind to const lvalue reference text = newPwd; // copy assignment } private: std::string text; }; int main() { std::string initPwd("Supercalifragilisticexpialidocious"); Password p(initPwd); std::string newPassword("Beware the Jabberwock"); // call newpassWord with lvalue. p.changeTo(newPassword); return 0; } Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 19 / 25
  • 20. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. cost of assignment call with lvalue text’s resouce is reusable text’s resource is not reusable Overloads 0 allocation & 0 deallocation 1 allocation & 1 deallocation both in copy asgnmt Universal 0 allocation & 0 deallocation 1 allocation & 1 deallocation both in copy asgnmt By value 1 allocation in copy ctor 1 allocation in copy ctor & 1 deallocation in move asgnmt 1 deallocation in move asgnmt call with rvalue text’s resouce is reusable text’s resource is not reusable Overloads 0 allocation & 1 deallocation 1 allocation & 1 deallocation Universal 0 allocation & 1 deallocation 1 allocation & 1 deallocation By value 0 allocation & 1 deallocation 1 allocation & 1 deallocation reusable : text.size() >= newPassword.size() Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 20 / 25
  • 21. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. penalty of pass by value with assignment と IF を選択する さいのアドバイス . Penalty を決定する要因 .. ...... パラメータの型 (リソースの取得と解放) 関数の呼ばれ方 (lvalue or rvalue) assignment operator の実装 (リソースの再利用) . 推定有罪 for Pass by value .. ...... assignment を使用してコピーしている場合、Pass by value を使用しても性能的に問 題ないと確認できるまで、Overloads/Universal reference を使用する。 . 性能を追求するソフトウェアでは Pass by value は使用しない .. ...... move1 回のコストは低くても、塵も積れば。 std::string f(std::string);// pass by value std::string g(std::string);// pass by value std::string h(std::string);// pass by value auto result = h(g(f(std::string("abc")))); // 4 moves Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 21 / 25
  • 22. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. Performance 以外の問題 (Slicing) 関数が引数を多相的に扱いたい場合、パラメータはポインタ、または、参照でなけれ ばいけない。 class Widget{}; class SpecialWidget : public Widget {}; // processWidgetはWidgetのサブ・タイプに対しても適用できる関数。 void processWidget(Widget w);// Pass by value SpecialWidget sw; // slicing。processWidgetはswをWidget型として扱う。 processWidget(sw); Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 22 / 25
  • 23. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. Review copyable & cheap-to-move & always copied なら、pass by value を使用すると、 実装が単純で、オブジェクト・コードのサイズが小さく、効率的なコードになる か もしれない 。 assingment より constructor の方がコストが高いときがある (リソースの再利 用)。 Slicing 問題があるので多相的にオブジェクトを使用したいときは pass by value は使用できない。 Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 23 / 25
  • 24. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. 実際? . Overloads は組合せの爆発。 .. ...... // 2引数に対して4 overloads。 void f(std::string v0, std::string v1); void f(const std::string& v0, const std::string& v1); void f(std::string&& v0, const std::string& v1); void f(std::string&& v0, std::string&& v1); . Universal reference はヘッダ依存 & コンパイル時間の増加。 ........ Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 24 / 25
  • 25. Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied. Pass by value for constructor Constructor で渡すパラメータはコピーされる。(メンバ変数の初期化で使用) メンバ変数の初期化は copy constructor で行なわれる。(初期化リスト) 気にしなければいけないのは copyable かどうかと cheap-to-move だけ。 class MyClass { public: MyClass(std::string v0, std::string v1) : v0_(std::move(v0)), v1_(std::move(v1)) {} private: std::string v0_; std::string v1_; }; Back to Basics! Essentials of Modern C++ Style@CPPCOn 2014 by Herb Sutter Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 25 / 25
  • 26. おまけ & 参考情報 . The evolving search for effective C++ - Keynote@Meeting C++ 2014 by Scott Meyers .. ...... Movie Slides . Back to Basics! Essentials of Modern C++ Style@CPPCOn 2014 by Herb Sutter .. ...... Movie Slides Mitsutaka Takeda Item 41. Consider pass by value for copyable parameters that are cheap to move and always copied.September 30, 2015 25 / 25