From: Charles Mills Date: 2005-01-28T07:45:54+09:00 Subject: Re: Extending Ruby Tim Sutherland wrote: > In article , Lyle Johnson wrote: > >On Fri, 28 Jan 2005 01:56:24 +0900, Asbj�rn Reglund Thorsen > > wrote: > > (...) > As an alternative to rb_ary_store(), you can access the buffer underlying > the Array directly: > > $result = rb_ary_new2(size); > for (int i = 0; i < size; ++i) > RARRAY($result)->ptr[i] = rb_float_new((double) p(i+1))); > > The latter is faster since it doesn't have to check things like > - 'Do we need to increase the buffer size' > - 'Is the buffer shared with another Array' > - 'Is the Array frozen' > ...etc. There is a gotcha to this though. rb_ary_new2(size) returns an array with length==0 and capacity==size. The example you give above never increases length. You could fix this with RARRAY($result)->len = size; However, this is also a gotcha. If you put it before the loop then the array is filled with a bunch of garabage references which will crash Ruby if the GC is run when rb_float_new() is called. If you put it after he loop then all those floats you create could be destroyed by the GC, causing Ruby to crash later. rb_ary_store() is the simplest and safest solution. You could also do: $result = rb_ary_new2(size); for ( ; RARRAY($result)->len < size; RARRAY($result)->len++) { int i = RARRAY($result)->len; RARRAY($result)->ptr[i] = rb_float_new((double) p(i+1))); } -Charlie