-1

パフォーマンスが重要なアプリケーションに c++ を使用することを検討しています。C と C++ の実行時間は同等になると思いました。ただし、C++ 関数は、同等の C スニペットを実行するのに 4 回以上かかることがわかります。

逆アセンブルを行ったとき、end()、++、!= がすべて関数呼び出しとして実装されていることがわかりました。それら (少なくともそれらの一部) をインラインにすることは可能ですか?

C++ コードは次のとおりです。

typedef struct pfx_s {
    unsigned int start;
    unsigned int end;
    unsigned int count;
} pfx_t;

typedef std::list<pfx_t *> pfx_list_t;

int
eval_one_pkt (pfx_list_t *cfg, unsigned int ip_addr)
{
    const_list_iter_t iter;

    for (iter = cfg->begin(); iter != cfg->end(); iter++) {
        if (((*iter)->start <= ip_addr) &&
            ((*iter)->end >= ip_addr)) {
            (*iter)->count++;
            return 1;
        }
    }
    return 0;
}

そして、これは同等の C コードです。

int
eval_one_pkt (cfg_t *cfg, unsigned int ip_addr)
{
    pfx_t *pfx;

    TAILQ_FOREACH (pfx, &cfg->pfx_head, next) {
        if ((pfx->start <= ip_addr) &&
            (pfx->end >= ip_addr)) {
            pfx->count++;
            return 1;
        }
    }
    return 0;
}
4

3 に答える 3

4

ここでリストを使用する本当に正当な理由はありますか? 一見するstd::vectorと、a の方が適しているように見えます。おそらく、オブジェクトのコンテナーだけでなく、ポインターのコンテナーも必要ないでしょう。

標準のアルゴリズムを使用して、かなりきれいに作業を行うこともできます。

typedef std::vector<pfx_t> pfx_list_t;

int
eval_one_pkt(pfx_list_t const &cfg, unsigned int ip_addr) {
    auto pos = std::find_if(cfg.begin(), cfg.end(),
        [ip_addr](pfx_t const &p) {
            return ip_addr >= p.begin && ip_addr <= p.end;
        });

    if (pos != cfg.end()) {
       ++(pos->count);
       return 1;
    }
    return 0;
}

ただし、私がそれを行っていた場合、代わりにそれを一般的なアルゴリズムに変えるでしょう。

template <class InIter>
int
eval_one_pkt(InIter b, InIter e, unsigned int ip_addr) {
    auto pos = std::find_if(b, e,
        [ip_addr](pfx_t const &p) {
            return ip_addr >= p.begin && ip_addr <= p.end;
        });

    if (pos != cfg.end()) {
       ++(pos->count);
       return 1;
    }
    return 0;
}

C と C++ とは関係ありませんが、範囲チェックをさらに最適化するには、次のような方法を試してみてください。

return ((unsigned)(ip_addr-p.begin) <= (p.end-p.begin));

最適化が有効になっている最新のコンパイラを使用すると、使用時にテンプレートが完全にインラインで展開されると予想されるため、おそらく関数呼び出しはまったく含まれないでしょう。

于 2013-06-22T22:12:03.030 に答える