copy and array length vs capacity. (Doc suggestion?)
Jon D via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Nov 23 20:14:33 PST 2015
On Tuesday, 24 November 2015 at 01:00:40 UTC, Steven
Schveighoffer wrote:
> On 11/23/15 7:29 PM, Ali Çehreli wrote:
>> On 11/23/2015 04:03 PM, Steven Schveighoffer wrote:
>> > On 11/23/15 4:29 PM, Jon D wrote:
>>
>> >> In the example I gave, what I was really wondering was if
>> there is a
>> >> difference between allocating with 'new' or with
>> 'reserve', or with
>> >> 'length', for that matter. That is, is there a material
>> difference
>> >> between:
>> >>
>> >> auto x = new int[](n);
>> >> int[] y; y.length = n;
>> >
>> > There is no difference at all, other than the function that
>> is called
>> > (the former will call an allocation function, the latter
>> will call a
>> > length setting function, which then will determine if more
>> data is
>> > needed, and finding it is, call the allocation function).
>>
>> Although Jon's example above does not compare reserve, I have
>> to ask:
>> How about non-trivial types? Both cases above would set all
>> elements to
>> ..init, right? So, I think reserve would be faster if copy()
>> knew how to
>> take advantage of capacity. It could emplace elements instead
>> of
>> copying, no?
>
> I think the cost of looking up the array metadata is more than
> the initialization of elements to .init. However, using an
> Appender would likely fix all these problems.
>
> You could also use
> https://dlang.org/phobos/std_array.html#uninitializedArray to
> create the array before copying. There are quite a few options,
> actually :)
>
> A delegate is also surprisingly considered an output range!
> Because why not? So you can do this too as a crude substitute
> for appender (or for testing performance):
>
> import std.range; // for iota
> import std.algorithm;
>
> void main()
> {
> int[] arr;
> arr.reserve(100);
>
> iota(100).copy((int a) { arr ~= a;});
> }
>
> -Steve
Thanks. I was also wondering if that initial allocation could be
avoided. Code I was writing involved repeatedly using a buffer in
a loop. I was trying out taskPool.amap, which needs a random
access range. This meant copying from the input range being read.
Something like:
auto input = anInfiniteRange();
auto bufsize = workPerThread * taskPool.size();
auto workbuf = new int[](bufsize);
auto results = new int[](bufsize);
while (true) {
input.take(bufsize).copy(workbuf);
input.popFront(bufsize);
taskPool.amap!expensiveCalc(workbuf, workPerThread,
results);
results.doSomething();
}
I'm just writing a toy example, but it is where these questions
came from. For this example, the next step would be to allow the
buffer size to change while iterating.
--Jon
More information about the Digitalmars-d-learn
mailing list