Re: resolving methods at compile time

2005-08-20 Thread Jim Cromie

Jim Cromie wrote:



I'll take this opportunity to note the existence of B::Generate & 
optimizer.pm,

with which you can do various function replacements / optimizations.

(btw, I have patches for them, so they properly compile & run,
on 5.6.2-nothread, 5.8.x-nothread, 5.9.3-thread)


FYI, Ive uploaded those patches to my CPAN folder.
Ive no idea (yet) whether theyll get indexed (and maybe they shouldnt 
just yet)


At this time, I would like to ask that fold_constants be added to the 
API,

or to some sort of meta-stable privileged API, so that *deep magic*
like that done by B::Generate, not be forever relegated to a
backwater / podunk / redhead-stepchild status.
Those 2 modules are too cool to let languish.


Hopefully they work for you, and they move the issue forward.
If not, send patches :-) or bug reports :-(

have the right amt of fun,
jimc


Re: resolving methods at compile time

2005-08-19 Thread Michael G Schwern
On Wed, Aug 17, 2005 at 12:00:18PM -0700, Philippe M. Chiasson wrote:
> This somewhat simplistic benchmark seems to indicate there actually is a 
> performance hit to using that form of my statement



> $> perl-5.8.6 bench-my.pl
> declared 127166/s   --  -6%
> normal   134590/s   6%   --

$ perl5.8.6 ~/tmp/foo.plx
 Rate declared   normal
declared 162068/s   --  -1%
normal   163959/s   1%   --
$ perl5.8.6 ~/tmp/foo.plx
 Rate declared   normal
declared 162444/s   --  -0%
normal   162474/s   0%   --
$ perl5.8.6 ~/tmp/foo.plx
 Rate declared   normal
declared 162103/s   --  -0%
normal   162893/s   0%   --
$ perl5.6.2 ~/tmp/foo.plx
Benchmark: running declared, normal, each for at least 15 CPU seconds...
  declared: 19 wallclock secs (15.56 usr +  0.00 sys = 15.56 CPU) @ 119003.86/s 
(n=1851700)
normal: 18 wallclock secs (15.35 usr +  0.09 sys = 15.44 CPU) @ 121247.47/s 
(n=1872061)
 Rate declared   normal
declared 119004/s   --  -2%
normal   121247/s   2%   --
$ perl5.6.2 ~/tmp/foo.plx
Benchmark: running declared, normal, each for at least 15 CPU seconds...
  declared: 18 wallclock secs (14.92 usr +  0.09 sys = 15.01 CPU) @ 124462.43/s 
(n=1868181)
normal: 18 wallclock secs (15.55 usr +  0.03 sys = 15.58 CPU) @ 116665.02/s 
(n=1817641)
 Rate   normal declared
normal   116665/s   --  -6%
declared 124462/s   7%   --
$ perl5.6.2 ~/tmp/foo.plx
Benchmark: running declared, normal, each for at least 15 CPU seconds...
  declared: 17 wallclock secs (15.94 usr +  0.00 sys = 15.94 CPU) @ 120326.35/s 
(n=1918002)
normal: 16 wallclock secs (15.62 usr +  0.03 sys = 15.65 CPU) @ 120341.15/s 
(n=1883339)
 Rate declared   normal
declared 120326/s   --  -0%
normal   120341/s   0%   --



No significant difference from where I'm sitting.  Different OSs, different
compilers, different versions of Perl and a heavy dose of Benchmark.pm 
flutter.


-- 
Michael G Schwern [EMAIL PROTECTED] http://www.pobox.com/~schwern
Don't try the paranormal until you know what's normal.
-- "Lords and Ladies" by Terry Prachett


Re: resolving methods at compile time

2005-08-18 Thread Jim Cromie

Nicholas Clark wrote:


On Thu, Aug 18, 2005 at 04:10:50PM -0500, David Nicol wrote:
 


Executive vote:
  more trouble than its worth (but D looks interesting)
   



This is the conclusion I'm coming to for just about all "speed"
optimisations, where the intent is to buy more speed by increasing
complexity.

I feel that we'd be much better served by attempting to simplify the current
code base (without losing functionality) and see whether that opens up any
new insights.

(As well as fixing bugs and generally increasing maintainability and
accessibility)

Nicholas Clark

 

I'll take this opportunity to note the existence of B::Generate & 
optimizer.pm,

with which you can do various function replacements / optimizations.

(btw, I have patches for them, so they properly compile & run,
on 5.6.2-nothread, 5.8.x-nothread, 5.9.3-thread)

I did so once, but I modified only Class->methods so that I didnt
inadvertently hose someone elses $flaregun->warn() calls.


At this time, I would like to ask that fold_constants be added to the API,
or to some sort of meta-stable privileged API, so that *deep magic*
like that done by B::Generate, not be forever relegated to a
backwater / podunk / redhead-stepchild status.
Those 2 modules are too cool to let languish.

thanks
jimc


Re: resolving methods at compile time

2005-08-18 Thread Nicholas Clark
On Thu, Aug 18, 2005 at 04:10:50PM -0500, David Nicol wrote:
> Executive vote:
>more trouble than its worth (but D looks interesting)

This is the conclusion I'm coming to for just about all "speed"
optimisations, where the intent is to buy more speed by increasing
complexity.

I feel that we'd be much better served by attempting to simplify the current
code base (without losing functionality) and see whether that opens up any
new insights.

(As well as fixing bugs and generally increasing maintainability and
accessibility)

Nicholas Clark


Re: resolving methods at compile time

2005-08-18 Thread David Nicol
On 8/18/05, Dave Mitchell <[EMAIL PROTECTED]> wrote:

> @Dog::ISA = qw(Mammal);
> ...
> my Mammal $x = new Dog;
> $x->foo(); # may be Dog::foo() or Mammal::foo()

As I hid in the middle of a wordy paragraph a few posts back in this thread, 

> [the proposed optimization] would break
> subclassing in the absense of explicitly marked virtual methods by the
> way, unless the explicit marking of the virtual methods would be done
> by the compiler, as in D

The optimizer would only optimize an op when there was only one possible
call, so it would have to not optimize when there's a chance of ambiguity.

When a method of the same name appears in a subclass, that method in
the base class gets flagged as virtual and may not be optimized. 

We can't control later addition of subclasses, but we can switch the optree to
a new CV and assign the old CV to the 'deoptimize thyself' routine, when a
method that has not been virtual before becomes virtual due to appearing in
a newly added subclass.  

Which implies tracking @ISBASEOF as well as @ISA.  Or does it?

When a new routine is defined, in the presence of an @ISA, @ISA gets traversed
and any colliding routines would get flagged as virtual and get
slapped if they have
been flagged as having optimized calls to them somewhere.

So in the example above, $x->foo could be optimized only if there are
no foo() methods
in any classes that inherit from Mammal, or also inherit from wherever
Mammal got its foo
method from.


In the list of features to abandon in C++,
(http://www.digitalmars.com/d/overview.html),
Digital Mars has this to say:

>  Non-virtual member functions. In C++, a class designer decides in advance if 
> a function is
> to be virtual or not. Forgetting to retrofit the base class member function 
> to be virtual when
> the function gets overridden is a common (and very hard to find) coding 
> error. Making all
> member functions virtual, and letting the compiler decide if there are no 
> overrides and
> hence can be converted to non-virtual, is much more reliable.

In Perl, of course, all functions are virtual.  When, and only when,
"there are no overrides,"
a conversion to a tighter binding may be appropriate.  And when an
override appears later,
we would need to be able to revert.

But what about --

  @upper::ISA = qw(middle);
  @middle::ISA = qw(lower);
  @lower::ISA = ();

when subs lower::foo and middle::foo both exist but no upper::foo exists,
a call

  (my middle $x = new upper)->foo

could be optimized, since lower::foo has been overridden but
middle::foo has not,
and $x is guaranteed to be a middle or something that inherits from middle.

  (my lower $x = new upper)->foo

could not be optimized.

Cost:
Two new flags on a CV, one flag for has-been-overridden and one flag for 
has-been-optimized, and code to check all these flags all the time

Benefit:
it becomes possible to make a non-noticeable performance improvement when
special syntax is used

Executive vote:
   more trouble than its worth (but D looks interesting)



> ops are in a tree of ops that are attached to a CV, [which is a kind of SV.]

Thanks.


Re: resolving methods at compile time

2005-08-18 Thread Dave Mitchell
On Thu, Aug 18, 2005 at 01:54:23PM -0500, David Nicol wrote:
> > This would not work. The same sub entry op may call many different
> > functions:
> > 
> > $_->foo() for qw(A B C::D);
> 
> Under discussion is optimizing in the case of typed localized variables.
> 
>   my dog $iggy;
>   $iggy->make_sound;  # bound early to dog::make_sound due to declared 
> type
> 
> not a general early binding.

@Dog::ISA = qw(Mammal);
...
my Mammal $x = new Dog;
$x->foo(); # may be Dog::foo() or Mammal::foo()

> >  [unifying ops and SVs] would be a Dumb Thing.
> 
> Do they have reference counts?  I guess I can look at the source for once.
> BASEOP in op.h does not appear to define reference count field.
> 
> Being able to recycle optree memory is another thing that would
> be more trouble than its worth.  But repeated eval-strings isn't a memory
> leak --- how do we do that now?  Mark and sweep? Return opnodes to
> a pool after an eval-string unless they get referred to  by something external
> to the eval?

ops are in a tree of ops that are attached to a CV. The head of the op
tree has a refcnt, so that the tree can be shared amongst several CVs.
When the last CV is freed, the tree is freed. Each OP struct is usually
indivdually malloced or freed, although there is code, not normally
enabled, to allocate them from arenas.

This is of course irrelvant as to whether unifying OPs and SVs
would be a good thing.

-- 
In the 70's we wore flares because we didn't know any better.
What possible excuse does the current generation have?


Re: resolving methods at compile time

2005-08-18 Thread David Nicol
On 8/17/05, Dave Mitchell <[EMAIL PROTECTED]> wrote:
> On Wed, Aug 17, 2005 at 03:37:13PM -0500, David Nicol wrote:
> > which could also AIUI benefit /slightly/ from binding the subroutine's
> > entry point directly to the node that calls it instead of looking the
> > entry point up in a hash,
> 
> This would not work. The same sub entry op may call many different
> functions:
> 
> $_->foo() for qw(A B C::D);

Under discussion is optimizing in the case of typed localized variables.

  my dog $iggy;
  $iggy->make_sound;  # bound early to dog::make_sound due to declared type

not a general early binding.


>  [unifying ops and SVs] would be a Dumb Thing.

Do they have reference counts?  I guess I can look at the source for once.
BASEOP in op.h does not appear to define reference count field.

Being able to recycle optree memory is another thing that would
be more trouble than its worth.  But repeated eval-strings isn't a memory
leak --- how do we do that now?  Mark and sweep? Return opnodes to
a pool after an eval-string unless they get referred to  by something external
to the eval?


Re: resolving methods at compile time

2005-08-18 Thread Philippe M. Chiasson
Stas Bekman wrote:
> A few years ago Doug MacEachern started to write code like:
> 
>   my Apache2::Connection $c = shift;
>   $c->foo; # should be already resolved
> 
> i.e. adding an explicit class name before the object. If I remember
> correctly he was saying that perl was supposed to optimise method
> lookups at compile-time. My question is: does it really work or is it
> still a wannabe? and if the latter what are the plans for making it
> really work?

This somewhat simplistic benchmark seems to indicate there actually is a 
performance
hit to using that form of my statement, even though both compiled subs look the
same to me.

package Test::Foo::A;
package main;

use Time::HiRes;
use Benchmark qw(cmpthese);

sub normal {
my $foo = Test::Foo::A->new;
$foo->test();
}

sub declared {
my Test::Foo $foo = Test::Foo::A->new;
$foo->test();
}

cmpthese(-15, {
normal => \&normal,
declared => \&declared,
});


package Test::Foo::C;
sub test { return 1; };
sub new { return bless {}, shift }

package Test::Foo::B;
use base qw(Test::Foo::C);

package Test::Foo::A;
use base qw(Test::Foo::B);

$> perl-5.8.6 bench-my.pl
declared 127166/s   --  -6%
normal   134590/s   6%   --


Philippe M. Chiasson m/gozer\@(apache|cpan|ectoplasm)\.org/ GPG KeyID : 88C3A5A5
http://gozer.ectoplasm.org/ F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3A5A5


signature.asc
Description: OpenPGP digital signature


Re: resolving methods at compile time

2005-08-18 Thread Fergal Daly
One problem was that if you pass in something which inherits from
Apache2::Connection you'd expect it to work. However if the object
overrides foo() it will be ignored, which is probably not what you
want to happen. A bit like static methods in C++,

F

On 8/17/05, Stas Bekman <[EMAIL PROTECTED]> wrote:
> A few years ago Doug MacEachern started to write code like:
> 
>my Apache2::Connection $c = shift;
>$c->foo; # should be already resolved
> 
> i.e. adding an explicit class name before the object. If I remember
> correctly he was saying that perl was supposed to optimise method lookups
> at compile-time. My question is: does it really work or is it still a
> wannabe? and if the latter what are the plans for making it really work?
> 
> Thanks.
> 
> --
> __
> Stas BekmanJAm_pH --> Just Another mod_perl Hacker
> http://stason.org/ mod_perl Guide ---> http://perl.apache.org
> mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
> http://modperlbook.org http://apache.org   http://ticketmaster.com
>


Re: resolving methods at compile time

2005-08-17 Thread Dave Mitchell
On Wed, Aug 17, 2005 at 03:37:13PM -0500, David Nicol wrote:
> which could also AIUI benefit /slightly/ from binding the subroutine's
> entry point directly to the node that calls it instead of looking the
> entry point up in a hash,

This would not work. The same sub entry op may call many different
functions:

$_->foo() for qw(A B C::D);

> I am not certain how much the data structures that hold the optree and
> SVs have in common at this time,

Absolutley nothing

> but I think unifying them would be a Good Thing

No, it would be a Dumb Thing.

-- 
O Unicef Clearasil!
Gibberish and Drivel!
  - "Bored of the Rings"


Re: resolving methods at compile time

2005-08-17 Thread Yuval Kogman
On Wed, Aug 17, 2005 at 12:19:25 -0700, Jan Dubois wrote:

> All of this is dead now, so I don't think type annotation serves any
> useful purpose anymore at all.

No no no!

'use fields' is there so that it can *retain* compatibility and
usefulness even when pseudohashes go out the door!

5.9's fields uses locked hashes, and there have been two patches on
p5p implementing compile time checks for this!


-- 
 ()  Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418  perl hacker &
 /\  kung foo master: /me climbs a brick wall with his fingers: neeyah!



pgptNtkj3Xfl1.pgp
Description: PGP signature


Re: resolving methods at compile time

2005-08-17 Thread David Nicol
On 8/17/05, Rick Delaney <[EMAIL PROTECTED]> wrote:

> 
> As for speeding up method lookups, aren't they cached after the first
> lookup anyway?  Isn't the slowness of method calls simply the slowness
> of subroutine calls?

which could also AIUI benefit /slightly/ from binding the subroutine's
entry point
directly to the node that calls it instead of looking the entry point
up in a hash,
even with a cached key value.  The cost would be (hey!  I just thought of
a way to reduce the cost! .. in a minute) keeping track of every point
that names a routine
so they can all get changed to the new routine if/when that routine
gets redefined,
the alternative being allowing the optimization only while some kind
of 'no redefinablesubs'
pragma is in effect.  A lot of work for a negligible speed-gain.

The thought I had three sentences ago is, if a magic SV
PL_subredefined was declared,
nodes that are optimized to refer to a routine's node directly,
without lookup, including
when a lookup would get optimized-away due to pointer typing, ( which
would break
subclassing in the absense of explicitly marked virtual methods by the
way, unless the
explicit marking of the virtual methods would be done by the compiler,
as in D, )
increment the reference count on that code entry point; and when a
subroutine gets
redefined late, the old code entry point's value is changed to &PL_subredefined
and whenever one of the cached calls to it discovers the magical
PL_subredefined value
there, (would undef work?) it goes and does the lookup, after
decrementing the old entry
point's refcount.  So the head node of old code would persist until
all the obsolete
optimized calls are revised, but the rest of the memory could be reused.

I am not certain how much the data structures that hold the optree and SVs have
in common at this time, but I think unifying them would be a Good
Thing and yes I
know its bad form to make suggestions without having the time to implement them
and I am ignorant concerning details of the internals.

DLN


Re: resolving methods at compile time

2005-08-17 Thread Rick Delaney
On Wed, Aug 17, 2005 at 12:19:25PM -0700, Jan Dubois wrote:
> 
> I thing the "type annotation" syntax was only used for the pseudohash
> support in fields.pm.  E.g. you could write:
> 
> my Type $self = shift;
> $self->{foo} = 1;
> 
> and if Type didn't have a field "foo" you would get a compile time error.

This is still the case.

> More importantly it would also change the hash access at compile time
> to an array access using the proper index.

This is not.

> All of this is dead now, so I don't think type annotation serves any
> useful purpose anymore at all.

Not quite dead.  Pseudohashes are dead but compile-time checking with
the fields pragma still works as before.  It would be pretty easy to
add the same kind of check for existance of methods.  The harder part
would be factoring the two out of the core in such a way as to enable
other useful add-ons.

As for speeding up method lookups, aren't they cached after the first
lookup anyway?  Isn't the slowness of method calls simply the slowness
of subroutine calls?

-- 
Rick Delaney
[EMAIL PROTECTED]


RE: resolving methods at compile time

2005-08-17 Thread Jan Dubois
On Wed, 17 Aug 2005, Stas Bekman wrote:
> 
> A few years ago Doug MacEachern started to write code like:
> 
>my Apache2::Connection $c = shift;
>$c->foo; # should be already resolved
> 
> i.e. adding an explicit class name before the object. If I remember
> correctly he was saying that perl was supposed to optimise method lookups
> at compile-time. My question is: does it really work or is it still a
> wannabe? and if the latter what are the plans for making it really work?

I thing the "type annotation" syntax was only used for the pseudohash
support in fields.pm.  E.g. you could write:

my Type $self = shift;
$self->{foo} = 1;

and if Type didn't have a field "foo" you would get a compile time error.
More importantly it would also change the hash access at compile time
to an array access using the proper index.

All of this is dead now, so I don't think type annotation serves any
useful purpose anymore at all.

I'm not aware that the type annotation has ever been used to speed up
method lookups, but obviously I could be wrong...

Cheers,
-Jan





Re: resolving methods at compile time

2005-08-17 Thread Dave Mitchell
On Wed, Aug 17, 2005 at 11:44:11AM -0700, Stas Bekman wrote:
> but what's the answer for my question? Does that declaration just gets 
> ignored?

A quick look at bleed src indicates that is only used to provide a stash
name when calling attribute handlers, ie in

my Stash $foo : attributes;

-- 
Red sky at night - gerroff my land!
Red sky at morning - gerroff my land!
-- old farmers' sayings #14


Re: resolving methods at compile time

2005-08-17 Thread Stas Bekman

Fergal Daly wrote:

One problem was that if you pass in something which inherits from
Apache2::Connection you'd expect it to work. However if the object
overrides foo() it will be ignored, which is probably not what you
want to happen. A bit like static methods in C++,


Thanks Fergal,

but what's the answer for my question? Does that declaration just gets 
ignored?



On 8/17/05, Stas Bekman <[EMAIL PROTECTED]> wrote:


A few years ago Doug MacEachern started to write code like:

  my Apache2::Connection $c = shift;
  $c->foo; # should be already resolved

i.e. adding an explicit class name before the object. If I remember
correctly he was saying that perl was supposed to optimise method lookups
at compile-time. My question is: does it really work or is it still a
wannabe? and if the latter what are the plans for making it really work?

Thanks.

--
__
Stas BekmanJAm_pH --> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com




--
__
Stas BekmanJAm_pH --> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


resolving methods at compile time

2005-08-17 Thread Stas Bekman

A few years ago Doug MacEachern started to write code like:

  my Apache2::Connection $c = shift;
  $c->foo; # should be already resolved

i.e. adding an explicit class name before the object. If I remember 
correctly he was saying that perl was supposed to optimise method lookups 
at compile-time. My question is: does it really work or is it still a 
wannabe? and if the latter what are the plans for making it really work?


Thanks.

--
__
Stas BekmanJAm_pH --> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com