я вот чего натворил
class myfunctor1
{
std::string & s_;
long pos_;
long numsPerPoint_;
public:
myfunctor1(std::string &s, long npp) : s_(s), pos_(0), numsPerPoint_(npp) {}
template<typename T>
void operator()(T c)
{
++pos_;
if (pos_ > numsPerPoint_ && c != '-')
{
pos_ = 1;
s_ = "." + s_;
}
s_ = c + s_;
}
};
class myfunctor2
{
std::string & s_;
long pos_;
long numsPerPoint_;
public:
myfunctor2(std::string &s, long npp, long skip)
: s_(s)
, pos_(skip ? skip : npp)
, numsPerPoint_(npp) {}
template<typename T>
void operator()(T c)
{
if (pos_ == 0)
{
pos_ = numsPerPoint_;
s_ += ".";
}
s_ += c;
--pos_;
}
};
const long step = 2;
void convert1(long long v, std::string & result)
{
std::ostringstream str;
str << v;
std::string s = str.str();
for_each(s.rbegin(), s.rend(), myfunctor1(result, step));
}
void convert2(long long v, std::string & result)
{
std::ostringstream str;
str << v;
std::string s = str.str();
long correct = (v < 0 ? 1 : 0);
long skip = (s.size() - correct) % step;
skip = skip ? skip : step;
skip += correct;
for_each(s.begin(), s.end(), myfunctor2(result, step, skip));
}
void convert3(long long v, std::string & result)
{
char str[40] = {0};
_snprintf(str, sizeof(str) - 1, "%I64d", v);
long len = strlen(str);
const char * c = str + len;
myfunctor1 f(result, step);
do
{
--c;
f(*c);
} while(c != str);
}
void convert4(long long v, std::string & result)
{
char str[40] = {0};
_snprintf(str, sizeof(str) - 1, "%I64d", v);
long len = strlen(str);
long correct = (v < 0 ? 1 : 0);
long skip = (len - correct) % step;
skip = skip ? skip : step;
skip += correct;
const char * c = str + len;
myfunctor2 f(result, step, skip);
for (const char * c = str; str + len != c; ++c)
{
f(*c);
}
}
void test(long long v)
{
{
std::string s;
convert1(v, s);
std::cout << s << std::endl;
}
{
std::string s;
convert2(v, s);
std::cout << s << std::endl;
}
{
std::string s;
convert3(v, s);
std::cout << s << std::endl;
}
{
std::string s;
convert4(v, s);
std::cout << s << std::endl;
}
}
typedef void (*funcpointer)(long long, std::string &);
void perf_test(const std::string & name, funcpointer f)
{
long n = 1000000;
std::cout << "Start test " << name << std::endl;
std::string s;
unsigned long beginTime = GetTickCount();
for (long i = 0; i != n; ++i)
{
s.clear();
f(-123456L, s);
}
unsigned long endTime = GetTickCount();
std::cout << "Done: " << n << " calls " << endTime - beginTime << " ms" << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
test(1);
test(-1);
test(12);
test(-12);
test(123);
test(-123);
test(1234);
test(-1234);
test(12345);
test(-12345);
test(123456);
test(-123456);
perf_test("reverse + stringstream",convert1);
perf_test("forward + stringstream",convert2);
perf_test("reverse + printf",convert3);
perf_test("forward + printf",convert4);
return 0;
}
результаты испытаний(без оптимизации /Od):
Start test reverse + stringstream
Done: 1000000 calls 13593 ms
Start test forward + stringstream
Done: 1000000 calls 6922 ms
Start test reverse + printf
Done: 1000000 calls 7828 ms
Start test forward + printf
Done: 1000000 calls 2188 ms
результаты испытаний(c оптимизации /O2):
Start test reverse + stringstream
Done: 1000000 calls 4734 ms
Start test forward + stringstream
Done: 1000000 calls 3344 ms
Start test reverse + printf
Done: 1000000 calls 2594 ms
Start test forward + printf
Done: 1000000 calls 1391 ms