6

メインループのあるゲームを作成しています。このループの1サイクルの間に、int値をstring約50〜100回に変換する必要があります。これまで私はこの関数を使用してきました:

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

しかし、FPSが〜120(この関数を使用しない場合)から〜95(使用している場合)に低下したため、あまり効率的ではないようです。

私の関数よりもはるかに効率的なint変換方法は他にありますか?string

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 に答える