• Status: Solved
• Priority: Medium
• Security: Public
• Views: 186

# 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;
0
CyberKnight
• 9
• 7
• 6
• +1
1 Solution

Commented:
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.

0

Commented:
move(arr1,arr2,sizeof(arr1));
0

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

best regards
hamed
0

Commented:
oh, sorry u want copy arr2 to arr1 therefor :

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

procedure Move(const Source; var Dest; Count: Integer);
0

Commented:
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.

0

Author 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[x,y]....
..is that right..?
0

Commented:
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

Commented:
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

Author 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[x,y]....
..is that right..?
0

Author 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[x,y]....
..is that right..?
0

Author 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[x,y]....
..is that right..?
0

Commented:
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

Author 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[x,y]....
..is that right..?
0

Author 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[x,y]....
..is that right..?
0

Author Commented:
Opps... Very sorry bout... those repeat posts.. not sure why, they happened..

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

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

Author Commented:
Ok, much better....

that seems to work, fine.

Thanx..!
0

Commented:
Ok, fine, then how about accepting my comment(s) as the answer?   :-)
0

Commented:
:-))
0

Commented:
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

Commented:
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

Commented:
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

Commented:
Delphi *will* free the old columns! Delphi has garbage collection for dynamic elements (strings, dynamic arrays and interfaces).
0

Author Commented:
Sorry for the long delay, Madshi.....

:-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.