WindowsのVisualStudioでpriority_queueに大量データを突っ込むと遅くなった

2月 11th, 2010 by tune Leave a reply »

という問題が職場であったのでそのメモ。Releaseモードだとすぐ処理出来るのにDebugモードだと無限ループに陥ったかのような挙動を示す質問をもらったので調べてみました。priority_queueというのはある値に戻づいて順序が保たれるqueueです。便利ですね。

再現コードはこれでOK、C++編(標準ライブラリ) 第7章 priority_queueを参考にさせて頂きました。

#include
#include
using namespace std;

int main()
{
    priority_queue qu;

    // 要素を追加
    for(int i=0; i<100000; i++){
        qu.push( i );
    }

    // 先頭要素を取り出して出力
    cout << qu.top() << endl;

    return 0;
}

VisualStudio2005で試したところDebugモードだと動いてはいるのですが、とにかく時間がかかります。途中で処理を止めたところpushに時間がかかっているようです。そこでpushの先を追って行くと下記のようなコードが見つかります。

_Vector_iterator()
       {       // construct with null vector pointer
       }

#if _HAS_ITERATOR_DEBUGGING
_Vector_iterator(pointer _Ptr, const _Container_base *_Pvector)
       : _Mybase(_Ptr, _Pvector)
       {       // construct with pointer _Ptr
       }

#elif _SECURE_SCL
_Vector_iterator(pointer _Ptr, const _Container_base *_Pvector)
       : _Mybase(_Ptr, _Pvector)
       {       // construct with pointer _Ptr
       }

#else
_Vector_iterator(pointer _Ptr)
       : _Mybase(_Ptr)
       {       // construct with pointer _Ptr
       }
#endif /* _HAS_ITERATOR_DEBUGGING */

これを見るとdefineの定義状況によって、毎回値の妥当性チェックが呼ばれているようです。
これが過度にパフォーマンスが落ちていた原因でしょう。

_HAS_ITERATOR_DEBUGGINGはデバッグビルドでのみ有効になるようですが、_SECURE_SCLはリリースビルドでも残るようです。何用の定義なのかは軽くググッた限りではわかりませんでした。2007-07-04 – 新言語 Xtalを作る日記が見つかったぐらいです。

回避策としては両defineを0に設定すれば動かなくなり、通常のRelease/Debugの時間差で収まるようになります。

Advertisement

Comments are closed.