6

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

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

但它似乎不是很有效,因为我遇到 FPS 从 ~120(不使用此功能)下降到 ~95(使用它时)。

有没有其他方法可以转换intstring比我的函数更有效的方法?

4

5 回答 5

9

范围是 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];
}
于 2013-02-02T11:41:03.147 回答
4

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

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

于 2013-02-02T11:43:05.720 回答
3

是的 - 回到 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比构造和使用字符串流快得多(尽管是非标准的)。

但是,在竞争共享库之间遇到了这个专业化的实例化和原始函数模板的实例化之间的名称冲突问题。

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

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 代码逆向工程的,而不是我从公司代码库创建并投入生产的版本。不过,我现在想不出我对它所做的任何其他重大修改。

于 2013-02-02T11:46:18.413 回答
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]);
于 2013-02-02T11:39:16.597 回答
1

我用这个:

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;
}

在函数的开头。

于 2014-01-22T21:11:16.530 回答