Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-28 Thread Vincent Snijders

Bihar Anwar schreef:

I've tried to use Move() instead of Copy(). Any objection with the following 
code?


Yes, at first glance without much thinking, I don't think it is safe. Did you think 
through the consequences of copying reference counted types (ansistring in this case 
 presumably)?




var
  a: array of string;


shortstring of ansistring?



SetLength(a, 5);
a[0] := 'aa'; a[1] := 'bb'; a[2] := 'cc'; a[3] := 'dd'; a[4] := 'ee';

System.Move(a[3], a[0], 2 * SizeOf(string) );// instead of  a := Copy(a, 3, 
2);
SetLength(a, 2);


Hmm, maybe you are lucky and this does work without crashes, because the contents of 
 the ansistrings are constants. If they were variable strings, then then the move 
would make a[3] and a[0] point to the same string (with reference count 1). The 
setlength would free it, because it frees the memory of the ansistring in a[3].


Vincent
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-28 Thread Henry Vermaak
On 28 April 2010 04:24, Bihar Anwar bihar_an...@rocketmail.com wrote:
 Ok, I'll try to observe the compiled code using debugger and benchmark it if 
 needed. BTW, what do you mean by allocating memory directly? Is there another 
 way to allocate memory for dynamic array besides using SetLength()?

I meant using allocmem, reallocmem, and friends, but that's tricky and
bug-prone.  And I can't see that it's going to give a massive speed
increase.

Henry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-28 Thread David Emerson
Vincent Snijders wrote:
 Bihar Anwar schreef:
  I've tried to use Move() instead of Copy(). Any objection with the following
  code?
 
 Yes, at first glance without much thinking, I don't think it is safe. Did you
 think through the consequences of copying reference counted types (ansistring
 in this case presumably)?

  System.Move(a[3], a[0], 2 * SizeOf(string) );
  SetLength(a, 2);
 

The above works great for me for non-reference counted types; I use it 
extensively (most common usage is adding an element into the middle of a sorted 
list. Incidentally, if doing this, it's also good to manage the length 
intelligently, so it does not need to reserve memory each time it adds one 
element. anyway..)

For ref-counted types, a couple extra operations are needed in order to keep 
all 
the reference counts correct.

Before the move: for all the data that is going to be destroyed, set it to nil 
(setting an ansistring/dynarray to nil does the same thing as setlength to 0 -- 
namely, it adjusts the reference count, and frees it if needed)

for i := 0 to 2 do a[i] := nil;
System.Move(a[3], a[0], 2 * SizeOf(ansistring) );

After the move: duplicated data will now have an inaccurate ref-count (e.g. ref 
count = 1 instead of the actual 2), so we have to use fillbyte to zero out the 
old refs.

fillbyte (a[2], 3*sizeof(ansistring), 0);
SetLength(a, 2);

Note: you're playing with fire here, be really really careful. If you make the 
tiniest error, your data will become corrupt and your program will crash, and 
there will be no warnings or anything to help you fix the horrific mess you've 
created. And I haven't tested the code above... I've written the same stuff 
many times, but I always scrutinize it super-carefully and test the living crud 
out of it.

Consider whether your potential performance increase will be worth hours of 
debugging -- I have spent those hours!! -- and potential crashes from 
unauthorized memory accesses.

Cheers,
David

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-28 Thread Henry Vermaak
On 28 April 2010 05:33, Bihar Anwar bihar_an...@rocketmail.com wrote:
 I've tried to use Move() instead of Copy(). Any objection with the following 
 code?

 var
  a: array of string;

 SetLength(a, 5);
 a[0] := 'aa'; a[1] := 'bb'; a[2] := 'cc'; a[3] := 'dd'; a[4] := 'ee';

 System.Move(a[3], a[0], 2 * SizeOf(string) );    // instead of  a := Copy(a, 
 3, 2);
 SetLength(a, 2);

You'll have to finalize the strings you are overwriting.

Henry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-28 Thread Bihar Anwar
Thank you very much Henry, David, and Vincent. I think, I must go back to the 
basic of reference counting. Special thanks to David for the detail explanation.



  
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-27 Thread dmitry boyarintsev
On Tue, Apr 27, 2010 at 5:42 PM, Bihar Anwar bihar_an...@rocketmail.com wrote:
 Just say, I have a dynamic array with size=5, and I want to delete elements 
 from the index 0 to 2. Is there a trick (the fastest way) to delete those 
 elements (0 to 2) without moving activities?

You won't do it faster than this:

var
 a: array of string;
 i : integer;

SetLength(a, 5);
a[0] := 'aa'; a[1] := 'bb'; a[2] := 'cc'; a[3] := 'dd'; a[4] := 'ee';

a[0]:=a[3];
a[1]:=a[4];
SetLength(a,2);

thanks,
dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-27 Thread Henry Vermaak
On 27 April 2010 14:42, Bihar Anwar bihar_an...@rocketmail.com wrote:
 Just say, I have a dynamic array with size=5, and I want to delete elements 
 from the index 0 to 2. Is there a trick (the fastest way) to delete those 
 elements (0 to 2) without moving activities?

 I've tried to make the dynamic array just pointing to 3rd element and set a 
 new length for it, but fpc generates an unhandled exception.

 var
  a: array of string;

 SetLength(a, 5);
 a[0] := 'aa'; a[1] := 'bb'; a[2] := 'cc'; a[3] := 'dd'; a[4] := 'ee';

 a := @sl[3];       // this is the trick, but it doesn't work.
 SetLength(a, 2)

I think the right way to do this is:

a := copy(a, 3, length(a) - 3);

Presumably copy optimizes this adequately.

Henry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-27 Thread Bihar Anwar
- Original Message 

From: Henry Vermaak henry.verm...@gmail.com
To: FPC-Pascal users discussions fpc-pascal@lists.freepascal.org
Sent: Tue, April 27, 2010 10:19:45 PM

I think the right way to do this is:
a := copy(a, 3, length(a) - 3);
Presumably copy optimizes this adequately.

Henry
___

Would Move() be faster, instead of Copy()?



  
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-27 Thread Henry Vermaak
On 27 April 2010 18:34, Bihar Anwar bihar_an...@rocketmail.com wrote:

 Would Move() be faster, instead of Copy()?

I guess so, have you tried to benchmark?  If you really need speed,
why don't you allocate the memory directly?

Henry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-27 Thread Bihar Anwar
Ok, I'll try to observe the compiled code using debugger and benchmark it if 
needed. BTW, what do you mean by allocating memory directly? Is there another 
way to allocate memory for dynamic array besides using SetLength()?



- Original Message 
From: Henry Vermaak henry.verm...@gmail.com
To: FPC-Pascal users discussions fpc-pascal@lists.freepascal.org
Sent: Wed, April 28, 2010 4:12:26 AM
Subject: Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

On 27 April 2010 18:34, Bihar Anwar bihar_an...@rocketmail.com wrote:

 Would Move() be faster, instead of Copy()?

I guess so, have you tried to benchmark?  If you really need speed,
why don't you allocate the memory directly?

Henry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal



  
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-27 Thread dmitry boyarintsev
On Wed, Apr 28, 2010 at 7:24 AM, Bihar Anwar bihar_an...@rocketmail.com wrote:
 Ok, I'll try to observe the compiled code using debugger and benchmark it if 
 needed. BTW, what do you mean by allocating memory directly? Is there another 
 way to allocate memory for dynamic array besides using SetLength()?

Copy() (from the existing dynamic array).
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

2010-04-27 Thread Bihar Anwar
I've tried to use Move() instead of Copy(). Any objection with the following 
code?

var
  a: array of string;

SetLength(a, 5);
a[0] := 'aa'; a[1] := 'bb'; a[2] := 'cc'; a[3] := 'dd'; a[4] := 'ee';

System.Move(a[3], a[0], 2 * SizeOf(string) );// instead of  a := Copy(a, 3, 
2);
SetLength(a, 2);



- Original Message 
From: dmitry boyarintsev skalogryz.li...@gmail.com
To: FPC-Pascal users discussions fpc-pascal@lists.freepascal.org
Sent: Wed, April 28, 2010 10:31:09 AM
Subject: Re: [fpc-pascal] Question about Deleting elements in Dynamic Array

On Wed, Apr 28, 2010 at 7:24 AM, Bihar Anwar bihar_an...@rocketmail.com wrote:
 Ok, I'll try to observe the compiled code using debugger and benchmark it if 
 needed. BTW, what do you mean by allocating memory directly? Is there another 
 way to allocate memory for dynamic array besides using SetLength()?

Copy() (from the existing dynamic array).
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal



  
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal