Formatの問題点

前回のFormatクラスは関数内部でstatic変数を使っているので
プログラムが終了し、このstatic変数が消滅したあと他のstatic変数から
Formatオブジェクトが生成されるとえらいめにあうことが判明。

struct SomethingStatic
{
~SomethingStatic()
{
(Format("$")%1).Value();
}
}

static SomethingStatic s;

これを避ける方法もいくつか歩けどstaticオブジェクトでFormatを使わないとか
一番初めにFormatのstaticを生成するとか、あまりよい方法ではないし
sprintfみたいにいつでも呼びたいのが当然なので修正してみる。
まずDEFINE_FORMAT_OPERATORマクロの


static const std::string cFormat( (b) );\

const std::string cFormat( (b) );\

とstaticじゃなくて毎度毎度生成する。(もちろん遅くなるはず)
それからcheck関数の中身を以下のようにする。(もちろん遅くなるはずorz)


bool Check(const std::string& format)
{
///*static*/ const std::string wArgTab[]=
//{
// "$1",
// "$2",
// "$3",
// "$4",
// "$5",
// "$6",
// "$7",
// "$8",
// "$9",
// "$10",
// "$11",
// "$12",
// "$13",
// "$14",
// "$15",
// "$16",
// "$17",
// "$18",
// "$19",
// "$20",
//};
//std::string::size_type index=fs.find(wArgTab[fi-1]);
//if(index!=std::string::npos)
//{
// fs.replace(index,wArgTab[fi-1].length(),format);
// return true;
//}
//return false;

char buf[16];
sprintf(buf,"$%d",fi);
std::string wArgTab(buf);
std::string::size_type index=fs.find(wArgTab);
if(index!=std::string::npos)
{
fs.replace(index,wArgTab.length(),format);
return true;
}
return false;
}

staticを使うことでstringオブジェクトの生成を減らしていたのが
毎回生成するので若干おそくなるはずで、計測結果。


前回の結果
2,804.7 (boost::format("%1% %2% %3$04d %4% %5%\n") %"abc" %3 %3 %c %ul).str();
1,581.2 (Format("$1 $2 $3 $4 $5\n") %"abc" %3 %CustomForm(3,"%04d") %c %ul).Value();
200.0 sprintf(buf,"%s %d %04d %c %d\n","abc",3,3,c,ul);

1,209.7 (boost::format("%1%\n") % "abc").str();
390.4 (Format("$1\n") %"abc").Value();
77.1 sprintf(buf,"%s\n","abc");

今回の結果
2,938.6 (boost::format("%1% %2% %3$04d %4% %5%\n") %"abc" %3 %3 %c %ul).str();
1,921.3 (Format("$1 $2 $3 $4 $5\n") %"abc" %3 %CustomForm(3,"%04d") %c %ul).Value();
195.9 sprintf(buf,"%s %d %04d %c %d\n","abc",3,3,c,ul);

1,176.6 (boost::format("%1%\n") % "abc").str();
441.0 (Format("$1\n") %"abc").Value();
65.5 sprintf(buf,"%s\n","abc");

多少の誤差はあるだろうけど、思ったより遅くなってないなあ・・