1

ユーザーから数値を取得し、文字列として文字で出力するコードを書いています。パフォーマンスの面でどちらが優れているかを知りたいのですが、次のようなifステートメントが必要です。

if (n < 100) {
    // code for 2-digit numbers
} else if (n < 1000) {
    // code for 3-digit numbers
} // etc..

または、数値を文字列に入れてその長さを取得し、それを文字列として処理します。

コードはC++で書かれています。

4

4 に答える 4

1

もちろんif-else速くなります。

2つの数値を比較するには、ビット単位で比較します(さまざまな方法がありますが、非常に高速な操作です)。

文字列の長さを取得するには、文字列を作成し、データを入力して、何らかの方法で長さを計算する必要があります(さまざまな方法がありますが、最も簡単な方法はすべての記号を数えることです)。もちろん、もっと時間がかかります。

簡単な例では、違いはわかりませんが。人々がそのようなことに関心を持っていることにしばしば驚かされます(不快感はありません)。0.003コードが実際には数秒ではなく数秒で実行される場合でも、違いはありませ0.001ん...このような低レベルの最適化は、この正確な場所がアプリケーションのボトルネックであることがわかった後で、確実な場合にのみ行う必要があります。パフォーマンスを適切な量だけ向上させることができます。

于 2012-10-12T09:49:28.180 に答える
0

測定してこれが本当にボトルネックになるまでは、パフォーマンスについて心配する必要はありません。

そうは言っても、以下はさらに高速になるはずです(読みやすくするために、0から99999999の範囲の型を使用すると仮定します)。

if (n < 10000) {
    // code for less or equal to 4 digits
    if (n < 100)
    {
       //code for less or equal to 2 digits
       if (n < 10)
          return 1;
       else
          return 2;
    }
    else
    {
       //code for over 2 digits, but under or equal to 4
       if (n>=1000)
          return 4;
       else
          return 3;
    }
} else {
    //similar
} // etc..

基本的に、それは二分探索のバリエーションです。最悪の場合、これは、最大桁数であるのとはO(log(n))対照的にO(n)かかります。n

于 2012-10-12T09:54:22.300 に答える
0

バリアントはstring遅くなります:

std::stringstream ss;       // allocation, initialization ...
ss << 4711;                 // parsing, setting internal flags, ...
std::string str = ss.str(); // allocations, array copies ...    

// cleaning up (compiler does it for you) ...
str.~string();
ss.~stringstream();         // destruction ...

より多くの...ことが起こっていることを示します。

コンパクトな(キャッシュに適した)ループ(分岐予測に適した)が必要な場合があります。

int num_digits (int value, int base=10) {
    int num = 0;
    while (value) {
        value /= base;
        ++num;
    }
    return num;
}

int num_zeros (int value, int base=10) {
    return num_decimal_digits(value, base) - 1;
}

状況によっては、キャッシュと予測に適しているため、関係演算子に基づくソリューションよりも高速になる場合があります。

テンプレート化されたバリアントを使用すると、コンパイラは部門に対していくつかのマイクロ最適化を実行できます。

template <int base=10>
int num_digits (int value) {
    int num = 0;
    while (value) {
        value /= base;
        ++num;
    }
    return num;
}
于 2012-10-12T12:41:05.050 に答える
0

答えは良いですが、相対的な時間について少し考えてみてください。

あなたが考えることができる最も遅い方法でさえ、プログラムはおそらく100マイクロ秒のようにほんの一瞬でそれを行うことができます。

次に来ることをする前に、おそらく500ミリ秒で数値を入力でき、さらに500ミリ秒で出力を読み取ることができる、想像できる最速のユーザーとのバランスを取ります。

OK、マシンは基本的に1000ミリ秒の間何もしません。結局のところ、プログラムが遅いとユーザーに思わせたくないので、途中で100マイクロ秒の間狂ったようにクランチする必要があります;-)

于 2012-10-12T14:18:16.243 に答える