Differentiate const flavors using CASE?

Oskar Linde oskar.lindeREM at OVEgmail.com
Thu Mar 22 04:20:19 PDT 2007


janderson skrev:

> Walter posted about this in another thread saying foreach_reverse was 
> that way because of some performance nitch.

That's right. The DMD compiler isn't able to inline functions containing 
loops. Also, it is unable to inline calls to compile time known const 
(invariant?) delegates. Instead of fixing that, a new special case 
keyword is introduced.

> I still think that 
> foreach_reverse is not the right way to do a reverse.  I think having it 
> as a member or free function is the best.

I Agree.

> The compiler should be able 
> to detect .reverses on primitive arrays and optimize them.

Or even better, fix the compiler issues with inlining. Here is a trivial 
reverse array viewer I've been using since long before foreach_reverse 
was introduced. It doesn't perform extremely well for the above 
mentioned reasons, but I've always been thinking that one day a decent 
compiler would generate close to optimal code out of this.

struct ReverseIterator(T:T[]) {
         T[] array;

         int opApply(int delegate(inout T) dg) {
                 for (int i = array.length-1; i >= 0; i--) {
                         if (auto status = dg(array[i]))
                                 return status;
                 }
                 return 0;
         }
}

ReverseIterator!(Array) reverseView(Array)(Array array) {
         ReverseIterator!(Array) iter = {array};
         return iter;
}

import std.stdio;
void main() {
         foreach(x; reverseView("abcdx"))
                 writefln("%s",x);
}

> Besides, how does the compiler currently optimize something written as 
> an opApply?

It doesn't.

The introduction of foreach_reverse resolved the above mentioned 
performance issue with iterating backwards over an array, but didn't 
resolve either:

* Iterating backwards over any other container/view that implements 
random access semantics.

* Efficiently implementing other view constructs, such as:

foreach(person; employees.select((Person p){ return p.age > 65; }))

foreach(t; str.tokenize(" "))

foreach(d; data.selectIndices(indexArray))

etc...

foreach_reverse doesn't generalize anything. A container that implements 
random access semantics will not automatically be foreach_reversible. 
Everyone wanting to make a standard container will have to implement a 
silly opApplyReverse method that serves no real use. The performance 
will not be any better than using a generic reverse viewer and this was 
the only argument for adding foreach_reverse.

IMHO, foreach_reverse is an aberration in so many ways and the sooner it 
is gone the better.

/Oskar



More information about the Digitalmars-d mailing list