Thread overview
Removing an array's last item(s)?
Jul 02, 2005
AJG
Jul 03, 2005
AJG
Jul 03, 2005
Chris Sauls
Jul 04, 2005
Stewart Gordon
Jul 08, 2005
Nick
Jul 08, 2005
Stewart Gordon
Jul 08, 2005
Nick
July 02, 2005
Hi there,

I have a string buffer and I need to remove the last item out every once in a while inside a loop. I see two options (both without templates):

# string buf;
# ...
#
# // [1] Resizing.
# buf.length = buf.length - 1;
#
# // [2] Slicing.
# buf = buf[0 .. length - 1];

My questions are:
[a] Which one do you guys recommend?
[b] Which one is more performant (at least in theory)?
[c] Is there a simpler/better/faster method that I haven't discovered?

Thanks a ton!
--AJG.

2B || !2B, that is the question. ================================
July 02, 2005
"AJG" <AJG_member@pathlink.com> wrote in message news:da541b$2qdu$1@digitaldaemon.com...

Resizing a buffer to smaller than its original size is quite fast, as the system doesn't have to see if the buffer is overstepping its bounds, and if so, copy it.

Slicing may be slightly more expensive, simply because it has to construct a new array reference.  It's more obvious to say "arr.length=arr.length-1" than "arr=arr[0..length-2]", so I'd say use the "length" version.


July 02, 2005
"Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:da6pq9$16f5$1@digitaldaemon.com...
> Slicing may be slightly more expensive, simply because it has to construct a new array reference.  It's more obvious to say "arr.length=arr.length-1" than "arr=arr[0..length-2]", so I'd say use the "length" version.

Oops, meant arr=arr[0..length-1].


July 03, 2005
Hi Jarrett,

>Resizing a buffer to smaller than its original size is quite fast, as the system doesn't have to see if the buffer is overstepping its bounds, and if so, copy it.

That makes sense. Anybody think otherwise?

>Slicing may be slightly more expensive, simply because it has to construct a new array reference.  It's more obvious to say "arr.length=arr.length-1" than "arr=arr[0..length-2]", so I'd say use the "length" version.

I'll do that. How about this, though. Why can't I do:

arr.length--;
// or
--arr.length;
// not even:
arr.length -= 1;
// must do:
arr.length = arr.length - 1;

Seems kind of weird to me. Why is there this arbitrary restriction? Aren't they all semantically equivalent? If so, I think the syntax should support it.

Thanks,
--AJG.


=======================
I sync, therefore I am.
July 03, 2005
AJG wrote:
> I'll do that. How about this, though. Why can't I do:
> 
> arr.length--;
> // or
> --arr.length;
> // not even:
> arr.length -= 1;
> // must do:
> arr.length = arr.length - 1;
> 
> Seems kind of weird to me. Why is there this arbitrary restriction? Aren't they
> all semantically equivalent? If so, I think the syntax should support it.

Well, while at first glance it sure isn't obvious, they actually aren't technically equivelant, because length is not a field/variable, its a property, and so it actually has method/function semantics.  So, doing:

# arr.length = arr.length - 1;

Is sugar for:

# arr.length(arr.length() - 1);

At least that's my understanding.  Personally I would think that ++/-- semantics could be provided, as long as the type of the property is appropriately integral, or else a class or struct defining op*Inc/op*Dec operators.  I think the main reasoning why it isn't legal currently was something to do with expressions like:

# arr[arr.length++] = 123;

In what order is this evaluated?  Personally I would have expected the index to be guaranteed to be evaluated fully before the rvalue, but from some old discussions I got the impression this actually isn't guaranteed.

-- Chris Sauls
July 04, 2005
Jarrett Billingsley wrote:
> "AJG" <AJG_member@pathlink.com> wrote in message news:da541b$2qdu$1@digitaldaemon.com...
> 
> Resizing a buffer to smaller than its original size is quite fast, as the system doesn't have to see if the buffer is overstepping its bounds, and if so, copy it.
<snip>

But it still needs to make sure arr.length-1 is non-negative.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
July 04, 2005
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:dab8e8$rqh$1@digitaldaemon.com...
> But it still needs to make sure arr.length-1 is non-negative.

I'd imagine that'd go away in the release version.  But you're right, it still has to make the check, although it's not as expensive as possibly copying the entire array when resizing to a larger size.


July 08, 2005
In article <da6pq9$16f5$1@digitaldaemon.com>, Jarrett Billingsley says...
>
>"AJG" <AJG_member@pathlink.com> wrote in message news:da541b$2qdu$1@digitaldaemon.com...
>
>Resizing a buffer to smaller than its original size is quite fast, as the system doesn't have to see if the buffer is overstepping its bounds, and if so, copy it.
>
>Slicing may be slightly more expensive, simply because it has to construct a new array reference.  It's more obvious to say "arr.length=arr.length-1" than "arr=arr[0..length-2]", so I'd say use the "length" version.

Also, perhaps not relevant to your case, but important in general: they are not equivalent if you plan on growing the array again later. If you use .length to shrink and then grow the array, it is likely that the array will stay in the same place. But if you use a slice and then grow that, it will _always_ make a copy.

Nick


July 08, 2005
Nick wrote:
<snip>
> Also, perhaps not relevant to your case, but important in general: they are not
> equivalent if you plan on growing the array again later. If you use .length to
> shrink and then grow the array, it is likely that the array will stay in the
> same place. But if you use a slice and then grow that, it will _always_ make a
> copy.

Wrong.

An array reference consists of only two pieces of data: length and starting address.  These pieces of information are identical whether you do

    arr.length = arr.length - 1;

or

    arr = arr[0..$-1];

and so they are indistinguishable.

OTOH if you make a slice that doesn't begin at the beginning of the array, then the slice doesn't have the starting address of any heap-allocated array, and so increasing the length will reallocate.

Stewart.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:- a->--- UB@ P+ L E@ W++@ N+++ o K- w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y
------END GEEK CODE BLOCK------
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
July 08, 2005
In article <dam6jc$apt$1@digitaldaemon.com>, Stewart Gordon says...
>
>An array reference consists of only two pieces of data: length and starting address.  These pieces of information are identical whether you do
>
>     arr.length = arr.length - 1;
>
>or
>
>     arr = arr[0..$-1];
>
>and so they are indistinguishable.
>
>OTOH if you make a slice that doesn't begin at the beginning of the array, then the slice doesn't have the starting address of any heap-allocated array, and so increasing the length will reallocate.
>
>Stewart.

You are indeed correct. Thanks for clearing that up.

Nick