Inability to dup/~ for const arrays of class objects

Peter Williams pwil3058 at bigpond.net.au
Mon Jun 3 20:38:12 PDT 2013


On 04/06/13 11:56, Steven Schveighoffer wrote:
> On Mon, 03 Jun 2013 20:06:14 -0400, Peter Williams
>> That's great news.  When I tried to implement what I described above
>> it didn't go as well as planned (because I'd misunderstood how much
>> gets allocated) and I was thinking that what's needed is a way to tell
>> the compiler how much to allocate at the start.  And now you tell me
>> there is a way.
>>
>> This is one of the things I like about learning D.  Almost every time
>> I say to myself "I wish there was an easier way to do this" it turns
>> out that there is :-).  Some of them are easier to discover than
>> others, though.
>
> I added the capacity, reserve, and assumeSafeAppend array methods when I
> updated the append code, it's been there for a while now, since the
> beginning of 2010.  It was cited in the article mentioned earlier too.
> You might want to re-read that part (it's near the end).

I'm finding that the mind tends to skip (even potentially useful) bits 
when reading about computer languages that are similar to ones that I'm 
familiar with.  I've had the same thing happen with Andrei's book i.e. 
when I discover something new I say to myself "Why didn't Andrei mention 
this?" only to discover (on rereading the pertinent section) that he did 
but it didn't register.  I've decided to reread his book cover to cover.

>
>>> The appending feature of D arrays/slices is intended to be "good enough"
>>> for most usages, not horrendously slow, but also not super-optimized for
>>> specific purposes.
>>>
>>> And yes, we still need linked lists, arrays are good for appending, but
>>> not inserting :)
>>
>> I use a = a[0..i] ~ v ~ a[i..$] for insertion into a sorted array as
>> I'm willing to pay the cost of allocation for the convenience of array
>> notation.  One advantage is that finding i is O(log(a.length)) instead
>> of O(a.length()).  I also reasoned that the compiler can use memcopy()
>> (or whatever its name is) to do the reallocation and therefore it
>> should be fairly quick.
>
> ugh.  Sorry, the performance miser in me must object :)
>
> There are better ways to do this, using range operations.  I'm pretty
> sure you could do it with std.algorithm.copy.
>
>> I also do a = a[0..i] ~ a[i + 1..$] to remove an item but am starting
>> to suspect this isn't as good an idea as for the insert.  Maybe
>> something like:
>>
>> auto tmp = a[i + 1..$];
>> a.length = i;
>> a ~= tmp;
>>
>> would be more efficient?
>
> No, because that will also reallocate,

Wouldn't the a.length = i prevent that?

> just like your original.  This
> one is REALLY easy to get right, because it can be done in place
> (assuming a is not const/immutable).
>
> You can even do:
>
> memmove(&a[i], &a[i + 1], a.length - i - 1);
> a.length--;
>
> For some reason, D doesn't support overlapping moves,

Probably because there's some instances where it would be a disaster and 
explaining all the cases where you can and can't becomes too difficult 
so it's just easier to say no to all cases.

> otherwise, this
> would work:
>
> a[i..$-1] = a[i + 1..$];
> a.length--;
>
> I think std.algorithm.remove can do the same thing in one line.

As I said somewhere else, there's a need for a book on Phobos.

Thanks
Peter


More information about the Digitalmars-d mailing list