C++ で何が速くなりますか?
ループまたは除算。ループのサイズは、除算される数値の桁数に匹敵します。
これは、1 つのループで除算なしで実行されます (C++11 の range-based を使用しますfor
が、簡単に書き直してなくても済みます)。
std::string s = "123";
int base = 10; // Must be <= 10, or the technique below won't work
int n = 0; for (char c : s) { n = n * base + (c - '0'); }
std::cout << n; // Should output 123
編集:
数字以外の文字が検出されるまで文字列を解析する、より安全でやや複雑なソリューション:
#include <iostream>
int convert(std::string const& s, int base)
{
int n = 0;
for (char c : s)
{
if (!isdigit(c)) { break; }
n = n * base + (c - '0');
}
return n;
}
int main()
{
std::string s = "123d";
cout << convert(s, 10) << endl; // Should output 123
}
2 つのループも必要ありません。整数を作成しているときは、ループが文字列の最後に達したらループを停止するだけです。これは、提案された両方のソリューションよりも高速です。
ゼロの初期番号から始めます。文字列内の各文字を左から右にたどり、数値に 10 を掛け、現在の桁の値を加算します。
ホーナーの法則を使用してください。つまり、C では、文字列が数字のみであると仮定します。
value = 0;
for(p = str; *p; p++)
value = 10 * value + *p - '0';
1 ループ、分割なし。
除算には一定の時間がかかります(結局のところ、これは命令です)。それをメモリのループと比較するには、ある程度の測定が必要です。そのような質問に答える出発点は、Jon Bentley が彼の "Programming pearls" で引用しているプログラムです。タイミングプログラムは、現在のシステムでコンパイルするために少し調整が必要で、一緒に実行されないように出力を調整する必要があります。そして、パフォーマンスのためにコードをマングリングすることを考える前に、コンパイラはしばしば驚くほどスマートであることを決して忘れないでください。