Solved

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

Posted on 2001-07-28
163 Views
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
Question by:CyberKnight
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• Learn & ask questions
• 9
• 7
• 6
• +1

LVL 20

Expert Comment

ID: 6329766
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

LVL 1

Expert Comment

ID: 6329787
move(arr1,arr2,sizeof(arr1));
0

LVL 1

Expert Comment

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

best regards
hamed
0

LVL 1

Expert Comment

ID: 6329793
oh, sorry u want copy arr2 to arr1 therefor :

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

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

LVL 20

Expert Comment

ID: 6329812
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 Comment

ID: 6329845
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

LVL 1

Expert Comment

ID: 6329847
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

LVL 1

Expert Comment

ID: 6329850
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 Comment

ID: 6329855
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

Author Comment

ID: 6329877
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

Author Comment

ID: 6329879
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

LVL 20

Expert Comment

ID: 6329881
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 Comment

ID: 6329899
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

Author Comment

ID: 6329942
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

Author Comment

ID: 6329957
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

LVL 20

Accepted Solution

Madshi earned 20 total points
ID: 6330067
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 Comment

ID: 6330158
Ok, much better....

that seems to work, fine.

Thanx..!
0

LVL 20

Expert Comment

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

LVL 1

Expert Comment

ID: 6330790
:-))
0

LVL 4

Expert Comment

ID: 6331291
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

LVL 20

Expert Comment

ID: 6331447
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

LVL 4

Expert Comment

ID: 6331458
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

LVL 20

Expert Comment

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

Author Comment

ID: 6351186
Sorry for the long delay, Madshi.....

:-)
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

### Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, thâ€¦
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usuaâ€¦
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201â€¦
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the adminiâ€¦
###### Suggested Courses
Course of the Month7 days, 3 hours left to enroll

#### 732 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.