Thread overview
Create uninitialized dynamic array
Oct 05, 2017
Igor Shirkalin
Oct 05, 2017
Adam D. Ruppe
Oct 05, 2017
Igor Shirkalin
Oct 05, 2017
Adam D. Ruppe
Oct 05, 2017
Adam D. Ruppe
Oct 05, 2017
Igor Shirkalin
October 05, 2017
Hello!

Preface:
I need 1G array of ints (or anything else).

Problem:
I want to quickly fill it with my own data and I do not want to waste CPU time to fill it with zeros (or some other value).


I do like this:


void main() {
    int[] data;
    // key code:
    data.length = SOMETHING; // how to create an array and leave it uninitialized?

    // fill 'data' with some data
    foreach(i, ref v; data) v=i; // an example
}

Is there a pure way to make what I want?

October 05, 2017
On Thursday, 5 October 2017 at 19:59:48 UTC, Igor Shirkalin wrote:
> I want to quickly fill it with my own data and I do not want to waste CPU time to fill it with zeros (or some other value).

You could always just allocate it yourself. Something that large is liable to be accidentally pinned by the GC anyway, so I suggest:

int[] data;
int* dataptr = cast(int*) malloc(SOMETHING * int.sizeof);
if(dataptr is null) throw new Exception("malloc failed");
scope(exit) free(dataptr);
data = dataptr[0 .. SOMETHING];
// work with data normally here


Just keep in mind it is freed at scope exit there, so don't escape slices into it.
October 05, 2017
On Thursday, 5 October 2017 at 20:19:15 UTC, Adam D. Ruppe wrote:
> On Thursday, 5 October 2017 at 19:59:48 UTC, Igor Shirkalin wrote:
>> I want to quickly fill it with my own data and I do not want to waste CPU time to fill it with zeros (or some other value).
>
> You could always just allocate it yourself. Something that large is liable to be accidentally pinned by the GC anyway, so I suggest:
>
> int[] data;
> int* dataptr = cast(int*) malloc(SOMETHING * int.sizeof);
> if(dataptr is null) throw new Exception("malloc failed");
> scope(exit) free(dataptr);
> data = dataptr[0 .. SOMETHING];
> // work with data normally here
>
>
> Just keep in mind it is freed at scope exit there, so don't escape slices into it.

Thank you, Adam, for pinpoint answer.

Doesn't it mean we have to avoid GC for such large blocks? And what if we need a lot blocks with less sizes? I'm from C++ world but... I like GC.
Usually the block(s) is scoped with some more complex way, so it is good to pass it to GC for management.
Maybe (say LDC) compiler can reject this unuseful initialization on simplest cases.

Shortly, I'm still in doubt.


October 05, 2017
On Thursday, 5 October 2017 at 20:52:00 UTC, Igor Shirkalin wrote:
> Doesn't it mean we have to avoid GC for such large blocks? And what if we need a lot blocks with less sizes?

No, it can work, especially if you are on 64 bit. Just if it is trivial I'd malloc it, but if the lifetime is nontrivial, sure, GC it.

The GC.malloc function from `import core.memory;` works just like malloc, except the garbage collector is aware of it and will collect eventually:

http://dpldocs.info/experimental-docs/core.memory.GC.malloc.html


int[] data = (cast(int*) GC.malloc(SOMETHING * int.sizeof, 0, typeid(int)))[0 .. SOMETHING];


Note that `typeid` returns the TypeInfo for that type, so you can pass it there.

Then the GC will collect if you like.

> Usually the block(s) is scoped with some more complex way, so it is good to pass it to GC for management.

Yeah, that's good too.
October 05, 2017
On Thursday, 5 October 2017 at 19:59:48 UTC, Igor Shirkalin wrote:
> Is there a pure way to make what I want?

oh i almost forgot about this function too:

http://dpldocs.info/experimental-docs/std.array.uninitializedArray.1.html


import std.array;
double[] arr = uninitializedArray!(double[])(100);


October 05, 2017
On Thursday, 5 October 2017 at 21:04:30 UTC, Adam D. Ruppe wrote:
> On Thursday, 5 October 2017 at 19:59:48 UTC, Igor Shirkalin wrote:
>> Is there a pure way to make what I want?
>
> oh i almost forgot about this function too:
>
> http://dpldocs.info/experimental-docs/std.array.uninitializedArray.1.html
>
>
> import std.array;
> double[] arr = uninitializedArray!(double[])(100);

Ha! I saw it some day and forgot too!

And GC.malloc is, I think, what I need.

Thank you!