www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Final makes no difference?

reply John Demme <me teqdruid.com> writes:
I'm working on fixing and optimizing my XML parser.  It uses some classes,
and lots of virtual method calls, so I figured I could really increase my
speed by making everything final.  I made the classes final, and I put all
of the methods in a big final{} block, but it made no appreciable
difference in my time trials.

Am I doing something wrong?  Does DMD currently not optimize for final?  Or
are virtual method calls not nearly as bad as I thought? I'm making a ton
of calls into small functions, so I was also hoping final methods would be
candidates for inlining...

I'm using DMD 0.163 and compiling with -O and -inline.

Thanks
-- 
~John Demme
me teqdruid.com
http://www.teqdruid.com/
Aug 24 2006
parent reply BCS <BCS pathlink.com> writes:
John Demme wrote:
 I'm working on fixing and optimizing my XML parser.  It uses some classes,
 and lots of virtual method calls, so I figured I could really increase my
 speed by making everything final.  I made the classes final, and I put all
 of the methods in a big final{} block, but it made no appreciable
 difference in my time trials.
 
 Am I doing something wrong?  Does DMD currently not optimize for final?  Or
 are virtual method calls not nearly as bad as I thought? I'm making a ton
 of calls into small functions, so I was also hoping final methods would be
 candidates for inlining...
 
 I'm using DMD 0.163 and compiling with -O and -inline.
 
 Thanks

if you aren't using inheritance, try using structs.
Aug 24 2006
parent reply John Demme <me teqdruid.com> writes:
BCS wrote:

 John Demme wrote:
 I'm working on fixing and optimizing my XML parser.  It uses some
 classes, and lots of virtual method calls, so I figured I could really
 increase my
 speed by making everything final.  I made the classes final, and I put
 all of the methods in a big final{} block, but it made no appreciable
 difference in my time trials.
 
 Am I doing something wrong?  Does DMD currently not optimize for final? 
 Or are virtual method calls not nearly as bad as I thought? I'm making a
 ton of calls into small functions, so I was also hoping final methods
 would be candidates for inlining...
 
 I'm using DMD 0.163 and compiling with -O and -inline.
 
 Thanks

if you aren't using inheritance, try using structs.

Yeah, I know... I'm probably going to switch several of the classes over to structs, but the big main class implements an interface. I don't absolultely need the speed right now- I'm just wondering if any changes will be made in the future, and if I'm expecting the right thing from final. -- ~John Demme me teqdruid.com http://www.teqdruid.com/
Aug 24 2006
parent reply BCS <BCS pathlink.com> writes:
John Demme wrote:
 BCS wrote:
 
 
John Demme wrote:

I'm working on fixing and optimizing my XML parser.  It uses some
classes, and lots of virtual method calls, so I figured I could really
increase my
speed by making everything final.  I made the classes final, and I put
all of the methods in a big final{} block, but it made no appreciable
difference in my time trials.

Am I doing something wrong?  Does DMD currently not optimize for final? 
Or are virtual method calls not nearly as bad as I thought? I'm making a
ton of calls into small functions, so I was also hoping final methods
would be candidates for inlining...

I'm using DMD 0.163 and compiling with -O and -inline.

Thanks

if you aren't using inheritance, try using structs.

Yeah, I know... I'm probably going to switch several of the classes over to structs, but the big main class implements an interface. I don't absolultely need the speed right now- I'm just wondering if any changes will be made in the future, and if I'm expecting the right thing from final.

That brings up another bone of mine. why can't struct implement an interface? For that matter why not a function? interface Foo { char fig(int); int bar(char); } void fun() { char[] cmap; int[] imap; char first(int i){return cmap[i];} int second(char c){return imap[c];} Foo f = interface : Foo // making up a syntax... { alias first fig; alias second bar; } FnTakingFoo(f); }
Aug 24 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
BCS wrote:
 
 That brings up another bone of mine. why can't struct implement an 
 interface? For that matter why not a function?

Structs don't support inheritance, which is arguably required for interface support. Sean
Aug 24 2006
parent BCS <BCS pathlink.com> writes:
Sean Kelly wrote:
 BCS wrote:
 
 That brings up another bone of mine. why can't struct implement an 
 interface? For that matter why not a function?

Structs don't support inheritance, which is arguably required for interface support. Sean

I don't see any technical problems for such a feature. From one perspective an instance of an interface is a multi-functioned delegate. e.i. delegate = {context*, function*} vs. interface = {context*, (function*)[]} the function array is constructed per-class, per-interface and the two are tacked together at assignment. Why then, couldn't a analogous array of function ptrs be gathered for a struct and used as an interface? It would be easier than with a class because the correct array of function can be found at compile time (vs. runtime for a class). The same argument could hold for any context that a delegate can use, specifically nested function. That said, I woudn't dream of this befor 2.0
Aug 24 2006
prev sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
BCS wrote:
 John Demme wrote:
 
 BCS wrote:


 John Demme wrote:

 I'm working on fixing and optimizing my XML parser.  It uses some
 classes, and lots of virtual method calls, so I figured I could really
 increase my
 speed by making everything final.  I made the classes final, and I put
 all of the methods in a big final{} block, but it made no appreciable
 difference in my time trials.

 Am I doing something wrong?  Does DMD currently not optimize for 
 final? Or are virtual method calls not nearly as bad as I thought? 
 I'm making a
 ton of calls into small functions, so I was also hoping final methods
 would be candidates for inlining...

 I'm using DMD 0.163 and compiling with -O and -inline.

 Thanks

if you aren't using inheritance, try using structs.

Yeah, I know... I'm probably going to switch several of the classes over to structs, but the big main class implements an interface. I don't absolultely need the speed right now- I'm just wondering if any changes will be made in the future, and if I'm expecting the right thing from final.

That brings up another bone of mine. why can't struct implement an interface? For that matter why not a function? interface Foo { char fig(int); int bar(char); } void fun() { char[] cmap; int[] imap; char first(int i){return cmap[i];} int second(char c){return imap[c];} Foo f = interface : Foo // making up a syntax... { alias first fig; alias second bar; } FnTakingFoo(f); }

Tested with DMD 0.165, no errors, runs perfectly: # module funcface0; # # import std .stdio ; # # interface Foo { # char[] str () ; # int num () ; # } # # void bar (Foo f) { # writefln("str('%s') num(%d)", f.str(), f.num()); # } # # void func (char[] s, int n) { # Foo f = new class Foo { # char[] str () { return s ; } # int num () { return n ; } # }; # bar(f); # } # # void main () { # func("The answer is", 42); # } I did try your trick of aliasing nested functions into the anonymous class' scope... Unfortunatley it didn't work; DMD complained the interface was left unimplemented. Not a really big deal, as anonymous classes apparently get access to the frame they were created in, the same as a delegate does I'd imagine. -- Chris Nicholson-Sauls
Aug 24 2006
next sibling parent BCS <BCS pathlink.com> writes:
Chris Nicholson-Sauls wrote:
 BCS wrote:

 interface Foo {
     char fig(int);
     int bar(char);
 }
 void fun()
 {
     char[] cmap;    int[] imap;

     char first(int i){return cmap[i];}
     int second(char c){return imap[c];}

     Foo f = interface : Foo {   // making up a syntax...
             alias first fig;
             alias second bar;
         }
     FnTakingFoo(f);
 }


Neat work-around! It does have the problem of double indirection in there: f.classContex.functionContext[offset_s] vs. f.functionContext[offset_s] But that's not that bad an issue. Having the alias trick fail is more of an issue, but still not a big one. (BTW I expect this fails because the aliased function ends up being static or some such problem) Also it is still a workaround that subverts something into something else it wasn't intended for. My main question why that syntax even works? Shouldn't there be a ":" between the "class" and the "Foo"?
 
 
 Tested with DMD 0.165, no errors, runs perfectly:
 
 # module funcface0;
 #
 # import std .stdio ;
 #
 # interface Foo {
 #   char[] str () ;
 #   int    num () ;
 # }
 #
 # void bar (Foo f) {
 #   writefln("str('%s')  num(%d)", f.str(), f.num());
 # }
 #
 # void func (char[] s, int n) {
 #   Foo f = new class Foo {
 #     char[] str () { return s ; }
 #     int    num () { return n ; }
 #   };
 #   bar(f);
 # }
 #
 # void main () {
 #   func("The answer is", 42);
 # }
 
 I did try your trick of aliasing nested functions into the anonymous 
 class' scope... Unfortunatley it didn't work; DMD complained the 
 interface was left unimplemented.  Not a really big deal, as anonymous 
 classes apparently get access to the frame they were created in, the 
 same as a delegate does I'd imagine.
 
 -- Chris Nicholson-Sauls

Aug 24 2006
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
Chris Nicholson-Sauls wrote:
 
 Tested with DMD 0.165, no errors, runs perfectly:
 
 # module funcface0;
 #
 # import std .stdio ;
 #
 # interface Foo {
 #   char[] str () ;
 #   int    num () ;
 # }
 #
 # void bar (Foo f) {
 #   writefln("str('%s')  num(%d)", f.str(), f.num());
 # }
 #
 # void func (char[] s, int n) {
 #   Foo f = new class Foo {
 #     char[] str () { return s ; }
 #     int    num () { return n ; }
 #   };
 #   bar(f);
 # }
 #
 # void main () {
 #   func("The answer is", 42);
 # }
 
 I did try your trick of aliasing nested functions into the anonymous 
 class' scope... Unfortunatley it didn't work; DMD complained the 
 interface was left unimplemented.  Not a really big deal, as anonymous 
 classes apparently get access to the frame they were created in, the 
 same as a delegate does I'd imagine.

That compiles? How weird. I'd expect the assignment to "Foo f" to fail with a "cannot convert class Foo to interface Foo" type error. Does DMD simply infer the relationship from the assignment? Sean
Aug 24 2006
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Sean Kelly wrote:
 Chris Nicholson-Sauls wrote:
 Tested with DMD 0.165, no errors, runs perfectly:

 # module funcface0;
 #
 # import std .stdio ;
 #
 # interface Foo {
 #   char[] str () ;
 #   int    num () ;
 # }
 #
 # void bar (Foo f) {
 #   writefln("str('%s')  num(%d)", f.str(), f.num());
 # }
 #
 # void func (char[] s, int n) {
 #   Foo f = new class Foo {
 #     char[] str () { return s ; }
 #     int    num () { return n ; }
 #   };
 #   bar(f);
 # }
 #
 # void main () {
 #   func("The answer is", 42);
 # }

 I did try your trick of aliasing nested functions into the anonymous 
 class' scope... Unfortunatley it didn't work; DMD complained the 
 interface was left unimplemented.  Not a really big deal, as anonymous 
 classes apparently get access to the frame they were created in, the 
 same as a delegate does I'd imagine.

That compiles? How weird. I'd expect the assignment to "Foo f" to fail with a "cannot convert class Foo to interface Foo" type error. Does DMD simply infer the relationship from the assignment? Sean

There is no class Foo. The class literal is an anonymous class which implements the Foo interface. That's what "new class Foo {..." means. (http://www.digitalmars.com/d/class.html - Anonymous Nested Classes) -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Aug 25 2006