2017-03-18 17 views
4

私はCライブラリのCプログラムでqsortを使用しています。期待どおりに動作するので、コンパイラで遊ぶことにしました。QsortとComparatorsの変わった動作。 C

コンパレータ1(私はこれを使用):

int compare (const void * a, const void * b) 
{ 
    if (*(double*)a > *(double*)b) return 1; 
    else if (*(double*)a < *(double*)b) return -1; 
    else return 0; 
} 

コンパレータ2:最初の1作品

int comp (const void *a, const void *b) 
{ 
    const double *ia = (const double *)a; // casting pointer types 
    const double *ib = (const double *)b; 
    return *ia - *ib; 
} 

は私がしたいよう。第2のものは第1のものと同じことをするはずです。私はプログラムが少し速く動くので、2番目のものを使いたいですが、それは本当に何も並べ替えていないことです!

私は、コンパレータ#2をより小さな配列で使用していることを確信しています。私がそこに何かを見逃していない限り。

+0

わかりやすい「最適化された」コンパレータは、実際に動作するように修正されたときでさえ、最も特定の状況を除いて、測定可能に高速です。 'qsort()'関数は、ポインタを介してコンパレータを呼び出していることに注意してください。そのオーバーヘッドは、この単純な関数のパフォーマンスを左右する可能性があります。 –

+0

'return * ia - * ib;'を 'double diff = * ia - * ib;に置き換えてみてください。 return *(int *)((char *)&diff + 4); 'それが与えるパフォーマンスを確認します。これは非常に実装固有のものであり、完全ではなく推奨されていませんが、sizeof(int)= 4のリトルエンディアンで動作する必要があります。それは単に「diff」の最上位32ビットワードを返します。また、その単語のビット内容が正のdiffのためにゼロでないと仮定します。 – nnn

答えて

7

第2のものは、第1のものと同じことをするはずです。

最初の一見では、それはすべきですが、より詳細な検討の結果、そうすべきではないことが分かります。

例えば、5.34.9を比較することを検討してください。最初の数字が2番目の数字よりも大きいことは明らかです。しかし、一方を他方から減算すると、に転化すると、intに変換され、qsortになると、5.34.9は等しくなります。0.4を生成します。

signumを2つの引数の違いに適用することです。残念ながら、Cの標準では定義されていません。 this Q&A for several good work-aroundsを参照してください。

+0

ええ、私はちょうどこれを考えていた...ありがとう! –

+0

@ Mpr.Moeそうです、 'int'の代わりに' double'を返すことはできません。なぜなら、 'qsort'はあなたが与えた関数ポインタが' int'を返すという前提でコンパイルされているからです。この仮定を破ると、未定義の動作が発生します。しかし、リンクされたQ&Aからのトリックはうまくいくでしょう。 – dasblinkenlight

+1

私はそれを読んでいます。とにかくパフォーマンスの向上が見込まれますか?私は比較を避けたかったので、今度はそれに戻ります。ここに何かがない? –

関連する問題