将int转换为字符串的有效方法

时间:2013-02-02 11:32:41

标签: c++ string performance int type-conversion

我正在制作一个游戏,其中我有一个主循环。在此循环的一个循环中,我必须将int值转换为string约50-100次。到目前为止,我一直在使用这个功能:

std::string Util::intToString(int val)
{
   std::ostringstream s;
   s << val;
   return s.str();
}

但它似乎没有那么高效,因为我遇到FPS从~120(不使用此函数)下降到~95(使用它时)。

还有其他方法可以将int转换为string,这比我的功能更有效吗?

5 个答案:

答案 0 :(得分:8)

  

它是1-72范围。我不必处理否定问题。

预先创建73个string个对象的数组/向量,并使用索引来获取字符串。返回const引用也可以节省分配/解除分配:

// Initialize smallNumbers to strings "0", "1", "2", ...
static vector<string> smallNumbers;

const string& smallIntToString(unsigned int val) {
    return smallNumbers[val < smallNumbers.size() ? val : 0];
}

答案 1 :(得分:4)

标准std::to_string功能可能很有用。

但是,在这种情况下,我想知道在返回时它是否可能是字符串的复制可能是一个很大的瓶颈?如果是这样,您可以将目标字符串作为参考参数传递给函数。但是,如果你有std::to_string,则编译器可能与C ++ 11兼容,并且可以使用移动语义而不是复制。

答案 2 :(得分:2)

是的 - 正如this previous answer中所探讨的那样,回归C中的函数:

namespace boost {
template<>
inline std::string lexical_cast(const int& arg)
{
    char buffer[65]; // large enough for arg < 2^200
    ltoa( arg, buffer, 10 );
    return std::string( buffer ); // RVO will take place here
}
}//namespace boost

理论上,这种新的专业化将在您定义它的其他翻译单元中生效。 ltoa比构建和使用字符串流更快 尽管是非标准的)。

但是,I've experienced problems在此专业化的实例化与原始函数模板的实例化之间,在竞争共享库之间存在名称冲突。

为了解决这个问题,我实际上只是给这个函数一个全新的名字:

template <typename T>
inline std::string fast_lexical_cast(const T& arg)
{
    return boost::lexical_cast<std::string>(arg);
}

template <>
inline std::string my_fast_lexical_cast(const int& arg)
{
    char buffer[65];

    if (!ltoa(arg, buffer, 10)) {
       boost::throw_exception(boost::bad_lexical_cast(
          typeid(std::string), typeid(int)
       ));
    }

    return std::string(buffer);
}

用法: std::string myString = fast_lexical_cast<std::string>(42);

免责声明:此修改是从Kirill的原始SO代码中反向设计的,不是我创建的版本,并从我公司的代码库投入生产。但是,我现在无法想到我对它做出的任何其他重大修改。

答案 3 :(得分:1)

这样的事情:

 const int size = 12;
 char buf[size+1];
 buf[size] = 0;
 int index = size;
 bool neg = false
 if (val < 0) {    // Obviously don't need this if val is always positive.
    neg = true;
    val = -val;
 }

 do
 {
     buf[--index] = (val % 10) + '0';
     val /= 10;
 } while(val);
 if (neg)
 {
    buf[--index] = '-';
 }
 return std::string(&buf[index]);

答案 4 :(得分:0)

我用这个:

void append_uint_to_str(string & s, unsigned int i)
{
    if(i > 9)
        append_uint_to_str(s, i / 10);
    s += '0' + i % 10;
}

如果您想要负面插入:

if(i < 0)
{
    s += '-';
    i = -i;
}

在功能开始时。