vectorのコピーよりswapのが早そう。

コピー元のデータ(vector)が壊れてもいい場合(コピー元が一時バッファの様な場合)、
vectorの要素コピーはoperator = ()よりswap()のが早そう。


以下チョーいい加減な検証プログラム。

#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>

typedef std::vector<std::string> Strings; // stringのvector

int main()
{
	int testNum = 1000;	// 試行回数

	double copyTotal = 0.0;
	double swapTotal = 0.0;
	double cb, ce, ct;
	double sb, se, st;


	for (int i = 0; i < testNum; ++i) {
		// 文字列リストをランダム生成する。
		// ↓の関数は、ランダムにリストサイズを決め、要素の文字列サイズもランダムで決め、
		// 文字列の内容もa-zからランダムで選んで埋める関数。
		Strings strings;
		int chars = MakeString(strings);

		// 生成した文字列のコピーを取っておく
		Strings forCopySrc, forSwapSrc;
		forCopySrc = strings;
		forSwapSrc = strings;

		Strings forCopyDst, forSwapDst;

		printf("Test %d: strs=%u, chars=%u", i, strings.size(), chars);

		// コピーの計測
		cb = GetCurrentTimeMicros();	// マイクロ秒で時刻計測をする関数。
		forCopyDst = forCopySrc;	// コピー。operator ()
		ce = GetCurrentTimeMicros();
		ct = ce - cb;
		copyTotal += ct;

		printf(" copy=%.15fsec. %s", ct, EqualsStrings(strings, forCopyDst) ? "[o]" : "[x]");
						// ↑は文字列リストの同値性を検証する関数。

		// swapの計測
		sb = GetCurrentTimeMicros();
		forSwapDst.swap(forSwapSrc);	// swap
		se = GetCurrentTimeMicros();
		st = se - sb;
		swapTotal += st;

		if (ct > st)  printf(" >");
		if (ct == st) printf(" = ");
		if (ct < st)  printf(" < ");
		
		printf(" swap=%.15fsec. %s", st, EqualsStrings(strings, forSwapDst) ? "[o]" : "[x]");

		printf("\n");
	}

	printf("Copy> Total:%f\n", copyTotal);
	printf("Swap> Total:%f (%f%%)\n", swapTotal, 100.0-swapTotal/copyTotal*100.0);

	getchar();		// 止めたいだけ。

	return 0;
}

ランダム生成で検証しているので、平均値とかは出せないけど、
VisualC++でもgcc(CentOS)でも、swapの方が99%早かった。圧倒的。


最初に挙げた例や、vectorの要素を移動したいだけであれば、
空のvectorとswapするのが最もパフォーマンスが出そう。




おまけ。↑で使ってる関数の中身。これまたテキトーですよと。

//// 文字列リストをランダム生成
typedef std::vector<std::string> Strings;
int MakeString(Strings& strings)
{
	int num = rand() % 1024;	// 生成文字列数
	int chars = 0;				// 合計文字数
	for (int i = 0; i < num; ++i) {
		int len = rand() % 2056;	// 文字数
		chars += len;
		strings.push_back(std::string());
		strings.back().resize(len);
		for (int k = 0; k < len; ++k) {
			strings.back()[k] = (rand() % 23) + 'a';	// a-zで適当に生成
		}
	}
	return chars;
}
//// 文字列リストの同値性を検証する
bool EqualsStrings(const Strings& ss1, const Strings& ss2)
{
	if (ss1.size() != ss2.size()) return false;

	Strings::const_iterator i1 = ss1.begin();
	Strings::const_iterator i2 = ss2.begin();
	for (; i1 != ss1.end(); ++i1, ++i2) {
		if (i1->compare(*i2) != 0) {
			return false;
		}
	}
	return true;
}
#if defined(_WIN32)
//// for Windows
#include <windows.h>
LARGE_INTEGER freq;
LARGE_INTEGER cnt;

inline double GetCurrentTimeMicros()
{
	QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&cnt));
	return static_cast<double>(cnt.QuadPart * 1000000L / freq.QuadPart) * 0.001f * 0.001f;
		// マイクロ秒単位に直して(1000000倍して周波数で割る)、
		// ミリ秒単位に直して、秒単位にに直して取得
}

#else
//// for GCC
#include <sys/time.h>
timeval t;
inline double GetCurrentTimeMicros()
{
	gettimeofday(&t, 0);
	return static_cast<double>(t.tv_sec) + static_cast<double>(t.tv_usec)/1000000.0;
}

#endif