>サイトの説明:
http://kmaebashi.com/programmer/devlang/array.htmlでは下記のコードが追加されています.
>#GCされないようにおまじない
>CRB_push_value(inter, &ret);
>
>CRB_pop_value(inter);
これは、ネイティブ関数内で確保したオブジェクトがGCされないように
スタックに積んでいるわけですが、この方法は、ネイティブ関数を書く人に
(面倒くさいという意味で)負担をかけますので、
Webページ版においても以下のページで方法を変更しています。
http://kmaebashi.com/programmer/devlang/crowbar_0_4_02.html
前者の方法が後者の方法に比べて優れているところは特にないと思いますので、
本の方では、最初から後者の方法で実装しているわけです。
本では、後者の方法について、171ページで説明しています。
>私の実行環境ではnew_array()関数でたまに(要素数が大きくなると)gc_mark()の
>ところで止まってしまいます.私の実装ミスか,その部分のコードが足りない
>せいなのか分からないので質問させていただきました.
crowbarのGCは単純なstop the world式のmark sweep GCなので、オブジェクト数が
増えてくるとmarkに時間がかかります。1次元の配列なら、多少数が多くても
オブジェクト数はひとつだからよいのですが、多次元ですと、現状の実装では
確保の途中で(無駄に)GCが動くのでかなり遅くなることがあります。new_array()の
中で不要なオブジェクトが増えることはないので、この間GCの発生を抑止する
方がよいのでしょうが、現状ではそうなっていません。
ひとまずこちらでは、100×100×100の配列程度であればすぐに返りましたが、
200×200×200だと30秒近く待たされました。
簡単にチューニングするには、crowbar.hのHEAP_THRESHOLD_SIZEを増やすという
方法があります。これは、どれだけのサイズのオブジェクトを確保したらGCを
動かすかという閾値で、現状では256KBになっています。