www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How array concatenation works... internally

reply Dnewbie <newbie d.com> writes:
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.
Apr 23 2018
next sibling parent Dnewbie <newbie d.com> writes:
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?
Apr 23 2018
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Apr 23 2018
parent Dnewbie <newbie d.com> writes:
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.
Apr 23 2018