string Cat1(string s,string t){return s+ '.' + t;}
void Cat2(const char* s,const char* t,char* o){sprintf(o,"%s.%s",s,t);}
char* Cat3(const char* s,const char* t)
{static char r[80]; sprintf(r,"%s.%s",s,t); return r;}
char* Cat4(const char* s,const char* t)
{char* p = (char*)malloc(strlen(s)+strlen(t)+2);
sprintf(p,"%s.%s",s,t); return p;}
|
Cat1 は string を使ったもの、Cat2,Cat3,Cat4 は char* を使ったものである。
比較基準としては、メモリ管理と実行効率であろうか。効率はどれも変わらないと思う。
メモリ管理については、Cat1 は問題無い。
Cat2 は、確保場所をユーザが用意する必要がある。
Cat3 は、関数側で確保するが、同時には使えないし、他に比べてメモリ効率が悪い。
(起動中ずっと確保し続けるので。)また、バッファあふれの可能性もある。
Cat4 は、関数側で確保するが、ユーザ側でリリースする必要があり、面倒である。
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
namespace std {
template <>
class back_insert_iterator<string> {
string* m_str;
public:
back_insert_iterator(string& s) : m_str(&s) {}
back_insert_iterator& operator*(){return *this;}
back_insert_iterator& operator++(){return *this;}
back_insert_iterator operator++(int){return *this;}
back_insert_iterator& operator=(char c){*m_str += c; return *this;}
};
}
int main()
{
char* p = "abc";
string s;
copy(p,p+3,back_inserter(s));
cout << s << endl;
}
|
#include <string>
#include <iostream>
#include "etime.h"
using namespace std;
int main()
{
string s, t = "test data for copy";
char p[80], *q = "test data for copy";
CETime e;
int i, n = 1000000;
e.Reset();
for (i=0;i<n;++i) s = t;
cout << e.Sec() << endl;
e.Reset();
for (i=0;i<n;++i) strcpy(p,q);
cout << e.Sec() << endl;
}
|
結果は、string の方が数倍遅い。これは、意外であった。
ちなみに、文字列の長さを長くすると、string のコピーは変わらないが、
strcpy は遅くなる。
#include <string>
#include <iostream>
#include "etime.h"
using namespace std;
string complate_name(const string& s,const string& t)
{
string r = s;
r += ' ';
r += t;
return r;
}
string complate_name2(const string& s,const string& t)
{
string r = t;
r.insert(r.begin(),' ');
r.insert(0,s);
return r;
}
string complate_name3(const string& s,const string& t)
{
return s + ' ' + t;
}
struct _String {
allocator<char> a;
char* ptr;
size_t len,res;
_String(const char* p,int l,const char* q,int m){
len = res = l+m+1; ptr = new char[len+1];
*ptr = 0; ++ptr; memcpy(ptr,p,l);
ptr[l] = ' '; memcpy(ptr+l+1,q,m);}
};
string complate_name4(const string& s,const string& t)
{
_String r(s.data(),s.size(),t.data(),t.size());
return *(string*)(&r);
}
int main()
{
CETime e;
string s = "Mike", t = "Smith";
int i, n = 100000;
e.Reset();
for (i=0;i<n;++i) complate_name (s,t);
cout << e.Sec() << endl;
e.Reset();
for (i=0;i<n;++i) complate_name2(s,t);
cout << e.Sec() << endl;
e.Reset();
for (i=0;i<n;++i) complate_name3(s,t);
cout << e.Sec() << endl;
e.Reset();
for (i=0;i<n;++i) complate_name4(s,t);
cout << e.Sec() << endl;
}
|
「考えられる限り最高速」ということで complate_name4 を作ったが、
注意して欲しいのは、VC++5 でしか動かないということである。
スピードは、complate_name より倍以上速くなっている。
但し、完全に正しいかどうかの自信はない。