Solved

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

Posted on 2001-07-28
24
156 Views
Last Modified: 2010-04-06
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
Comment
Question by:CyberKnight
  • 9
  • 7
  • 6
  • +1
24 Comments
 
LVL 20

Expert Comment

by:Madshi
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.

Regards, Madshi.
0
 
LVL 1

Expert Comment

by:h_mohsenian
ID: 6329787
move(arr1,arr2,sizeof(arr1));
0
 
LVL 1

Expert Comment

by:h_mohsenian
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

by:h_mohsenian
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

by:Madshi
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.

Regards, Madshi.
0
 

Author Comment

by:CyberKnight
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

by:h_mohsenian
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

by:h_mohsenian
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

by:CyberKnight
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

by:CyberKnight
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

by:CyberKnight
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

by:Madshi
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:CyberKnight
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

by:CyberKnight
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

by:CyberKnight
ID: 6329957
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
 
LVL 20

Accepted Solution

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

by:CyberKnight
ID: 6330158
Ok, much better....

that seems to work, fine.

Thanx..!
0
 
LVL 20

Expert Comment

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

Expert Comment

by:h_mohsenian
ID: 6330790
:-))
0
 
LVL 4

Expert Comment

by:Neutron
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

by:Madshi
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

by:Neutron
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

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

Author Comment

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

:-)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

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

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

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now