Re: [fpc-pascal] Question about Deleting elements in Dynamic Array
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
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
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
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
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
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
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
- 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
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
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
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
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