Thread overview
Final makes no difference?
Aug 24, 2006
John Demme
Aug 24, 2006
BCS
Aug 24, 2006
John Demme
Aug 24, 2006
BCS
Aug 24, 2006
Sean Kelly
Aug 24, 2006
BCS
Aug 24, 2006
BCS
Aug 24, 2006
Sean Kelly
Aug 25, 2006
Bruno Medeiros
August 24, 2006
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/
August 24, 2006
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.
August 24, 2006
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/
August 24, 2006
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);
}
August 24, 2006
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
August 24, 2006
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
August 24, 2006
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
August 24, 2006
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
August 24, 2006
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
August 25, 2006
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