C++

スコープのパフォーマンスを手軽に測定

More than 3 years have passed since last update.

昨今ではxcodeみたいに、標準で
パフォーマンス測定用の環境があったりしますが、
ある程度負荷のかかっている箇所が想定できる場合なんかは
サクッとコードを仕込んでログ出力により調査できると
気軽だったりする時があります。

C++では変数のライフタイムの仕組みを活用すれば、
簡単に実現できるかもしれません。

例えば、こんな風に

class ScopedProfile
{
public:
    ScopedProfile( const char* name, uint32_t line )
    : _startClock( clock() )
    , _name( name )
    , _line( line )
    {}
    ~ScopedProfile(){
        printf( "[%s:%u] %f sec.\n", _name, _line, (double)( clock() - _startClock ) / CLOCKS_PER_SEC );
    }
private:
    clock_t _startClock;
    uint32_t _line;
    const char* _name;
};

マクロ化もしちゃいます。
マクロは毛嫌いする人もいますが、
用途が明確でコード解析を乱雑化しないものであれば
有用かと思います。

#if 1
#define ScopedProfile_ ScopedProfile ScopedProfile##__LINE__(__PRETTY_FUNCTION__, __LINE__);
#else
#define ScopedProfile_
#endif

テストしてみます。

static void TestScopedProfile(){
    auto var = new uint32_t[10000000];
    {
        ScopedProfile_
        for( int i = 0; i < 10000000; ++i ){
            var[i] = 0;
        }
    }
    {
        ScopedProfile_
        memset(var, 0, sizeof(uint32_t)*10000000);
    }
    delete[] var;
}

手持ちのiPhone5Sでdebugビルドを実行した結果です。

[void TestScopedProfile():39] 0.080048 sec.
[void TestScopedProfile():45] 0.004837 sec.

64bit環境でのmemsetの速度を調べたいわけではなかったのですが、
随分と差が出てました。

それは今回の目的ではないので置いておいて、
負荷の気になる「頻繁に呼ばれない程度のロジック」があれば、
こんな感じのプチ・プロファイラを仕込んでおくのも素敵かと思います。