What is the FASTEST way to assign a dynamic 2 dimensional array to another.

I have two 2 dimensional arrays...
I need the contents of 1 copied to the other.
I've found out that Arr1:=Arr2 does not work.

Currently Im using the code below, and it works...
Is there anyway I can do it faster..?

Var
  Arr1, Arr2 : Array of array of Integer;
  Rows     :Integer;
Begin
  SetLength(Arr1,100, 50);
  SetLength(Arr2,100, 50);

  For Rows := 0 to 99 do
     Arr1[Rows]:= Copy(Arr2[Rows],0,50);
End;
CyberKnightAsked:
Who is Participating?
 
MadshiConnect With a Mentor Commented:
I'm sorry, I gave you wrong information. The function "b := Copy(a)" works fine on 1d arrays only. When being used on 2d arrays, it works like "b := a". That's not good, Borland...   :-(

Here comes the solution. I don't like it too much (because IMO Borland should do that for us), but it works.

type T2d = array of array of integer;

procedure Copy2d(const a1: T2D; var a2: T2D);
var i1 : integer;
begin
  i1 := Length(a1);
  for i1 := 0 to i1 - 1 do
    Move(pointer(a1[i1])^, pointer(a2[i1])^, Length(a1[i1]) * 4);
end;

P.S: When you call this function, both arrays must have be created already and must have exactly the same size(s).
0
 
MadshiCommented:
Hi again!

Just do this:

type T2dInteger = array of array of integer;

var arr1, arr2 : T2dInteger;
begin
  arr1 := Copy(arr2);

This is the easiest and fastest solution.

Regards, Madshi.
0
 
h_mohsenianCommented:
move(arr1,arr2,sizeof(arr1));
0
2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

 
h_mohsenianCommented:
u could use this method for copy 2 var from the same ( exactly ) type , like here

best regards
hamed
0
 
h_mohsenianCommented:
oh, sorry u want copy arr2 to arr1 therefor :

move(arr2,arr1,sizeof(arr2)); cuz :

procedure Move(const Source; var Dest; Count: Integer);
0
 
MadshiCommented:
Hi hamed, that doesn't work for 2-dimensional dynamic arrays, because a 2-dimensional dynamic array is internally something like a pointer to an array of pointers.

Regards, Madshi.
0
 
CyberKnightAuthor Commented:
Hi guys...

Hamed, Madshi is right about that "Move" bit, U cant really do that.... I've tried ;-)

Madshi, what if I need to do it for 2D dynamic array ?

Im writting this graphic effect, ...which uses the 2D array as a "shading" map...

I could use a 1 D array and then use that method :-
arr1 := Copy(arr2);

But...then when Im doing calculations and stuff, it would be a bit slower.. eg...
pixel at x=40 y =50 then becomes
         array[y*width+x] (which is slow)...instead of
         array[x,y]....
..is that right..?
0
 
h_mohsenianCommented:
sorry,

Madshi is right , it dose not work here, exactly becouse of that he said.this way have been a magic way for me and helped me alot , but not for this problem ;-)

hamed ;-)

0
 
h_mohsenianCommented:
dear CyberKnight ,
you are right too, i did not see your comment becouse i was testing my code , and when i send my comment , i saw your comment too.

sorry again
hamed
0
 
CyberKnightAuthor Commented:
Hi guys...

Hamed, Madshi is right about that "Move" bit, U cant really do that.... I've tried ;-)

Madshi, what if I need to do it for 2D dynamic array ?

Im writting this graphic effect, ...which uses the 2D array as a "shading" map...

I could use a 1 D array and then use that method :-
arr1 := Copy(arr2);

But...then when Im doing calculations and stuff, it would be a bit slower.. eg...
pixel at x=40 y =50 then becomes
         array[y*width+x] (which is slow)...instead of
         array[x,y]....
..is that right..?
0
 
CyberKnightAuthor Commented:
Hi guys...

Hamed, Madshi is right about that "Move" bit, U cant really do that.... I've tried ;-)

Madshi, what if I need to do it for 2D dynamic array ?

Im writting this graphic effect, ...which uses the 2D array as a "shading" map...

I could use a 1 D array and then use that method :-
arr1 := Copy(arr2);

But...then when Im doing calculations and stuff, it would be a bit slower.. eg...
pixel at x=40 y =50 then becomes
         array[y*width+x] (which is slow)...instead of
         array[x,y]....
..is that right..?
0
 
CyberKnightAuthor Commented:
Hi guys...

Hamed, Madshi is right about that "Move" bit, U cant really do that.... I've tried ;-)

Madshi, what if I need to do it for 2D dynamic array ?

Im writting this graphic effect, ...which uses the 2D array as a "shading" map...

I could use a 1 D array and then use that method :-
arr1 := Copy(arr2);

But...then when Im doing calculations and stuff, it would be a bit slower.. eg...
pixel at x=40 y =50 then becomes
         array[y*width+x] (which is slow)...instead of
         array[x,y]....
..is that right..?
0
 
MadshiCommented:
Did you miss my first comment? You can simply use Copy on a 2d dynamic array. It really worx...

>> ..is that right..?

Yes, but Delphi does the same when you use a 2d static array! (It's different with a 2d dynamic array, because there the internal structure is different).
0
 
CyberKnightAuthor Commented:
Hi guys...

Hamed, Madshi is right about that "Move" bit, U cant really do that.... I've tried ;-)

Madshi, what if I need to do it for 2D dynamic array ?

Im writting this graphic effect, ...which uses the 2D array as a "shading" map...

I could use a 1 D array and then use that method :-
arr1 := Copy(arr2);

But...then when Im doing calculations and stuff, it would be a bit slower.. eg...
pixel at x=40 y =50 then becomes
         array[y*width+x] (which is slow)...instead of
         array[x,y]....
..is that right..?
0
 
CyberKnightAuthor Commented:
Hi guys...

Hamed, Madshi is right about that "Move" bit, U cant really do that.... I've tried ;-)

Madshi, what if I need to do it for 2D dynamic array ?

Im writting this graphic effect, ...which uses the 2D array as a "shading" map...

I could use a 1 D array and then use that method :-
arr1 := Copy(arr2);

But...then when Im doing calculations and stuff, it would be a bit slower.. eg...
pixel at x=40 y =50 then becomes
         array[y*width+x] (which is slow)...instead of
         array[x,y]....
..is that right..?
0
 
CyberKnightAuthor Commented:
Opps... Very sorry bout... those repeat posts.. not sure why, they happened..

Madshi...

Ive tried your "Copy" bit...for the 2 D array... I really dont think it works....

Ive written some sample code.. Please try this out.

The following code uses both a static 2d array, and a dynamic 2 D array.

Currently it uses the "static" array method to produce some stupid effect.
The program is tranferring 1 array to the other, integer by integer, to make sure, that is correct.

When U switch the arrays declarations from static to dynamic and change the copy method to use the method you suggested, the effect is different.

try this

If U just copy the code below and try it, it put a dot on a black rectangle, and then expands the white circle..until the rectangle is covered.

If we change it to dynamic...-
-   Comment out the lines with {1} // comment the static stuff
-   Uncomment the lines with {2}   //uncomment the dynamic stuff

...and the effect is different...

Help....
----------------------------
{$R+}
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
Const MaxX=40;
      MaxY=50;

Type T2d=array of array of Integer;
var
  Form1: TForm1;

{1}    B, OldB:array [0..MaxY-1, 0..MaxX-1] of Integer;
{2}//    B,OldB:T2d;
    BMP:TBitMap;
implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
 BMP:=TBitMap.Create;
 BMP.Width:=MaxX;
 BMP.Height:=MaxY;

{2}// SetLength(OldB,MaxY,MAxX);
{2}// SetLength(   B,MaxY,MAxX);

// Just put a white dot
   B[MaxY div 2,MaxX div 2]:=255;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  BMP.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
Var X,Y:Integer;
begin
{1}   for Y := 0 to MaxY-1 do  // tranfser 1 to the other.
{1}     for X := 0 to MaxX-1 do  //long unoptimized method for a copy.
{1}       OldB[Y,x]:=B[Y,x];
{2}//OldB:=Copy(B);               // transfer 1 to the other

  for Y := 1 to MaxY-2 do
  Begin
    for X := 1 to MaxX-2 do
    begin
      // Some effect that eventually fills the whole area.
      B[Y,X]:=
         (OldB[Y,X-1]+ OldB[Y,X+1]+
          OldB[Y-1,X]+ OldB[Y+1,X]) div 2;

      //Clips color
      If B[Y,X] > 255 then B[Y,X] :=255;
      //Set the color;
      BMP.Canvas.Pixels[X,Y]:=RGB(B[Y,X],B[Y,X],B[Y,X]);
    End;
  End;
  //Draw on form
  Form1.Canvas.Draw(0,0,BMP);
end;

end.

0
 
CyberKnightAuthor Commented:
Ok, much better....

that seems to work, fine.

Thanx..!
0
 
MadshiCommented:
Ok, fine, then how about accepting my comment(s) as the answer?   :-)
0
 
h_mohsenianCommented:
:-))
0
 
NeutronCommented:
Did anyone run any performance tests of...

i1 := Length(Arr1);
For Rows := 0 to i1 do
  Arr1[Rows]:= Copy(Arr2[Rows],0,50);

...against...

i1 := Length(a1);
for i1 := 0 to i1 - 1 do
  Move(pointer(a1[i1])^, pointer(a2[i1])^, Length(a1[i1]) * 4);

Greetings,
    Ntr:)
0
 
MadshiCommented:
No, I have not. But the Copy will probably be a lot slower, because it will probably Free the old columns and reallocate them. I would bet on that Move is faster in this situation...   :-)
0
 
NeutronCommented:
You are right.
There is even a possibility that Delphi will not free old columns... (is there any garbage collection in Delphi?)

Greetings,
    Ntr:)
0
 
MadshiCommented:
Delphi *will* free the old columns! Delphi has garbage collection for dynamic elements (strings, dynamic arrays and interfaces).
0
 
CyberKnightAuthor Commented:
Sorry for the long delay, Madshi.....

:-)
0
All Courses

From novice to tech pro — start learning today.