move コンストラクタが入ったので、STLコンテナを使っているコードは、ソースコードを変えなくても速くなることがあるよ、という話。
つまり。
コンパイラオプションを -std=c++98
から -std=c++11
に変えるだけで速くなることがある。
#コード
実際に 100倍以上速くなるコードは下記の通り:
c++11_or_c++98
//clang++ -O2 -std=c++11 strvec.cpp
// or
//clang++ -O2 -std=c++98 strvec.cpp
#include <vector>
#include <time.h>
#include <utility>
#include <iostream>
#include <string>
double getTick()
{
timespec t;
clock_gettime(CLOCK_REALTIME, &t);
return t.tv_sec + t.tv_nsec*1e-9;
}
int const N1 = 10000;
int const N2 = 5000;
std::vector<std::string> prepare()
{
std::vector<char> v(N1);
std::fill(v.begin(), v.end(), 'a' );
std::vector<std::string> r;
for( int i=0 ; i<N2 ; ++i ){
r.push_back(std::string(v.begin(), v.end()));
}
return r;
}
void test( char const * title )
{
std::vector<std::string> a = prepare();
double tick = -getTick();
while( 0<a.size() ){
a.erase( a.begin() );
}
tick += getTick();
std::cout << title << ": " << tick << std::endl;
}
int main()
{
#if 201103L<=__cplusplus
test("c++11");
#else
test("c++98");
#endif
return 1;
}
結果
手元のマシンでの実行結果は下表の通り:
オプション | 出力 |
---|---|
-O2 -std=c++98 | c++98: 8.22603 |
-O2 -std=c++11 | c++11: 0.0721948 |
タイトルは「100倍以上」としたけど、N1
と N2
を調整して 100倍ちょっとになるようにしたんであって、1000倍にも1万倍にもなる。
で。
冒頭に書いたとおり、moveコンストラクタが導入されているのが原因。
細かく書くと:
-
std::string
にnoexcept
な moveコンストラクタがある - moveコンストラクタは、コピーコンストラクタよりもずっと速い
-
std::vector
がerase
内で 要素型の moveコンストラクタを利用している
ということが原因。
C++11 はなんとなく auto
・ラムダ・std::thread
あたりに注目していたんだけど、ソースコードそのままで高速化する場合があるとは思っていなかった。面白い。