Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2001-07-28
24
Medium Priority
?
177 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 

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 80 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Is your OST file inaccessible, Need to transfer OST file from one computer to another? Want to convert OST file to PST? If the answer to any of the above question is yes, then look no further. With the help of Stellar OST to PST Converter, you can e…
Suggested Courses

877 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