Thread overview
How array concatenation works... internally
Apr 23, 2018
Dnewbie
Apr 23, 2018
Dnewbie
Apr 24, 2018
Dnewbie
April 23, 2018
Hi,

I'd like to understand how array concatenation works internally, like the example below:

//DMD64 D Compiler 2.072.2
import std.stdio;
void main(){
    string[] arr;
    arr.length = 2;
    arr[0] = "Hello";
    arr[1] = "World";
    writeln(arr.length);
    arr = arr[0..1] ~ "New String" ~ arr[1..2];
    writeln(arr.length);
    foreach(string a; arr){
        writeln(a);
    }
}
http://rextester.com/DDW84343

The code above prints:
2
3
Hello
New String
World


So, It changes the "arr" length and put the "New String" between the other two. It's very fast with some other tests that I made.

Now I'm curious to know what's happening under the hood. It's related to memcpy?

On Phobos "array.d" source I've found this:

    /// Concatenation with rebinding.
    void opCatAssign(R)(R another)
    {
        auto newThis = this ~ another;
        move(newThis, this);
    }

But now I'm having problem to find how I can reach this "move" function, since I couldn't find any "move" on the "std" folder.

Thanks in advance.
April 23, 2018
On Monday, 23 April 2018 at 23:15:13 UTC, Dnewbie wrote:
> It's related to memcpy?

By the way... It's related to realloc and memcpy?

April 23, 2018
On 4/23/18 7:15 PM, Dnewbie wrote:
> Hi,
> 
> I'd like to understand how array concatenation works internally, like the example below:
> 
> //DMD64 D Compiler 2.072.2
> import std.stdio;
> void main(){
>      string[] arr;
>      arr.length = 2;
>      arr[0] = "Hello";
>      arr[1] = "World";
>      writeln(arr.length);
>      arr = arr[0..1] ~ "New String" ~ arr[1..2];
>      writeln(arr.length);
>      foreach(string a; arr){
>          writeln(a);
>      }
> }
> http://rextester.com/DDW84343
> 
> The code above prints:
> 2
> 3
> Hello
> New String
> World
> 
> 
> So, It changes the "arr" length and put the "New String" between the other two. It's very fast with some other tests that I made.

What it has done is built a completely new array, with the new 3 elements. The old array is still there. You can witness this by keeping a reference to the old array:

auto arr2 = arr;
arr = arr[0 .. 1] ~ "New String" ~ arr[1 .. 2];
writeln(arr2);
writeln(arr);

> Now I'm curious to know what's happening under the hood. It's related to memcpy?

There's not much copying going on here, each string is stored in the arr as a pointer and length pair. So you are just making a copy of those.

> On Phobos "array.d" source I've found this:
> 
>      /// Concatenation with rebinding.
>      void opCatAssign(R)(R another)
>      {
>          auto newThis = this ~ another;
>          move(newThis, this);
>      }

This is different. The builtin arrays are not part of phobos, they are defined by the compiler. std.array.Array is a different type.

If you want to know more about the array runtime, I suggest this article: https://dlang.org/articles/d-array-article.html

> But now I'm having problem to find how I can reach this "move" function, since I couldn't find any "move" on the "std" folder.

Move is std.algorithm.move: https://dlang.org/phobos/std_algorithm_mutation.html#.move

-Steve
April 24, 2018
On Monday, 23 April 2018 at 23:27:17 UTC, Steven Schveighoffer wrote:
>...
> If you want to know more about the array runtime, I suggest this article: https://dlang.org/articles/d-array-article.html
>...

Thanks for replying and this article is what I was looking for.