ファイナライザを登録したときの速度低下について

バージョン

この記事の内容は、Boehm GC 7.1で確認しました。

詳細

ファイナライザを登録した場合

以下のように、Boehm GCを使ってメモリを確保し、ファイナライザを登録するコードを書きます。

#include "gc.h"

static void 
finalizer(void* obj, void* client_data) 
{
    /* empty */
}

int 
main(int argc, char* argv[]) 
{
    int i = 0;
    for (i = 0; i < 10000000; i++) {
        void* p = GC_MALLOC(32);
        GC_REGISTER_FINALIZER(p, finalizer, NULL, NULL, NULL);
    }

    return 0;
}

このコードをmain.cとし、Boehm GCをgc-7.1というディレクトリに置いて、以下のようにしてコンパイルします。

$ gcc -lpthread -Igc-7.1/include main.c gc-7.1/.libs/libgc.a

このコードの実行時間をtimeコマンドで計測すると、以下のように、6.1sec程度になりました。

$ time ./a.out
./a.out  5.91s user 0.01s system 96% cpu 6.140 total
$ time ./a.out
./a.out  5.98s user 0.00s system 96% cpu 6.172 total
$ time ./a.out
./a.out  5.97s user 0.02s system 97% cpu 6.164 total
ファイナライザを登録しなかった場合

次に、以下のように、上のコードからファイナライザを登録する箇所を削除します。

#include "gc.h"

static void 
finalizer(void* obj, void* client_data) 
{
    /* empty */
}

int 
main(int argc, char* argv[]) 
{
    int i = 0;
    for (i = 0; i < 10000000; i++) {
        void* p = GC_MALLOC(32);
#if 0
        GC_REGISTER_FINALIZER(p, finalizer, NULL, NULL, NULL);
#endif
    }

    return 0;
}

同様にしてコンパイルします。

gcc -lpthread -Igc-7.1/include main.c gc-7.1/.libs/libgc.a

この場合の実行時間は、以下のように、2sec程度になりました。

$ time ./a.out
./a.out  2.10s user 0.01s system 97% cpu 2.163 total
$ time ./a.out
./a.out  2.13s user 0.00s system 96% cpu 2.206 total
$ time ./a.out
./a.out  2.12s user 0.00s system 93% cpu 2.262 total

ファイナライザの登録の有無で、相当なパフォーマンスの低下が見られるようです。

原因

調査中です。