Re: resolving methods at compile time
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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