Skip Menu |
Report information
Id: 126520
Status: new
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: david.warring <david.warring [at] gmail.com>
Cc:
AdminCc:

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Subject: Proxy objects - frequent FETCHs
Consider the following, which should be a simple and conventional use of Perl 6 Proxy objects: class C { has $!foo; method foo is rw { say "foo"; $!foo; } has $!bar; method bar is rw { Proxy.new( say "proxy new"; FETCH => sub ($) { say "bar fetch"; $!bar }, STORE => sub ($, $v) { say "bar store"; $!bar = $v; }, ); } } my $c = C.new; say "FETCHES"; $c.foo; $c.bar; say "STORES"; $c.foo++; $c.bar++; OUTPUT: FETCHES foo proxy new bar fetch bar fetch bar fetch STORES foo proxy new bar fetch bar fetch bar fetch bar fetch bar fetch bar fetch bar fetch bar store =================== In the above example, the bar proxy is called 10x whereas foo is called twice. In particular, the proxy FETCH is called 7X to do a simple increment. I'm raising this because this is the 'hot path' in projects such as https://github.com/p6-pdf/perl6-PDF-Tools. Would like to see this reduced, if possible.
Download (untitled) / with headers
text/plain 1.6k
Correct to test case, (say in wrong position): class C { has $!foo; method foo is rw { say "foo"; $!foo; } has $!bar; method bar is rw { say "proxy new"; Proxy.new( FETCH => sub ($) { say "bar fetch"; $!bar; }, STORE => sub ($, $v) { say "bar store"; $!bar = $v; }, ); } } my $c = C.new; say "FETCHES"; $c.foo; $c.bar; say "STORES"; $c.foo++; $c.bar++; On Sat Oct 31 12:09:05 2015, david.warring wrote: Show quoted text
> Consider the following, which should be a simple and conventional use > of Perl 6 Proxy objects: > > class C { > has $!foo; > method foo is rw { > say "foo"; > $!foo; > } > > has $!bar; > method bar is rw { > Proxy.new( > say "proxy new"; > FETCH => sub ($) { > say "bar fetch"; > $!bar > }, > STORE => sub ($, $v) { > say "bar store"; > $!bar = $v; > }, > ); > } > } > > my $c = C.new; > say "FETCHES"; > $c.foo; > $c.bar; > say "STORES"; > $c.foo++; > $c.bar++; > > OUTPUT: > > FETCHES > foo > proxy new > bar fetch > bar fetch > bar fetch > STORES > foo > proxy new > bar fetch > bar fetch > bar fetch > bar fetch > bar fetch > bar fetch > bar fetch > bar store > > =================== > In the above example, the bar proxy is called 10x whereas foo is > called twice. > > In particular, the proxy FETCH is called 7X to do a simple increment. > > I'm raising this because this is the 'hot path' in projects such as > https://github.com/p6-pdf/perl6-PDF-Tools. > > Would like to see this reduced, if possible.
Here's an attempt at bench-marking proxy objects, vs a simple home-baked accessor: use Bench; class C { has $!foo; method foo is rw { $!foo; } has $!bar; method bar is rw { Proxy.new( FETCH => sub ($) { $!bar; }, STORE => sub ($, $v) { $!bar = $v; }, ); } } my $c = C.new; Bench.new.cmpthese(1000, { simple-rw => { $c.foo = 42; $c.foo++ for 1..10; }, proxy-rw => { $c.bar = 42; $c.bar++ for 1..10; }, }); # results Benchmark: Timing 1000 iterations of proxy-rw, simple-rw... proxy-rw: 1.1713 wallclock secs @ 853.7233/s (n=1000) simple-rw: 0.0149 wallclock secs @ 66935.9365/s (n=1000) O-----------O---------O-----------O----------O | | Rate | simple-rw | proxy-rw | O===========O=========O===========O==========O | simple-rw | 66933/s | -- | 7740% | | proxy-rw | 854/s | -99% | -- | ---------------------------------------------- Proxys look like an expensive option at the moment. - David On Sat Oct 31 13:45:28 2015, david.warring wrote: Show quoted text
> Correct to test case, (say in wrong position): > > class C { > has $!foo; > method foo is rw { > say "foo"; > $!foo; > } > > has $!bar; > method bar is rw { > say "proxy new"; > > Proxy.new( > FETCH => sub ($) { > say "bar fetch"; > $!bar; > }, > STORE => sub ($, $v) { > say "bar store"; > $!bar = $v; > }, > ); > } > } > > my $c = C.new; > say "FETCHES"; > $c.foo; > $c.bar; > say "STORES"; > $c.foo++; > $c.bar++; > > On Sat Oct 31 12:09:05 2015, david.warring wrote:
> > Consider the following, which should be a simple and conventional use > > of Perl 6 Proxy objects: > > > > class C { > > has $!foo; > > method foo is rw { > > say "foo"; > > $!foo; > > } > > > > has $!bar; > > method bar is rw { > > Proxy.new( > > say "proxy new"; > > FETCH => sub ($) { > > say "bar fetch"; > > $!bar > > }, > > STORE => sub ($, $v) { > > say "bar store"; > > $!bar = $v; > > }, > > ); > > } > > } > > > > my $c = C.new; > > say "FETCHES"; > > $c.foo; > > $c.bar; > > say "STORES"; > > $c.foo++; > > $c.bar++; > > > > OUTPUT: > > > > FETCHES > > foo > > proxy new > > bar fetch > > bar fetch > > bar fetch > > STORES > > foo > > proxy new > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar store > > > > =================== > > In the above example, the bar proxy is called 10x whereas foo is > > called twice. > > > > In particular, the proxy FETCH is called 7X to do a simple increment. > > > > I'm raising this because this is the 'hot path' in projects such as > > https://github.com/p6-pdf/perl6-PDF-Tools. > > > > Would like to see this reduced, if possible.
> >
Download (untitled) / with headers
text/plain 1.4k
Show quoted text
MadcapJake> m: class N { method text { return Proxy.new: FETCH => method () { say 'fetch: ', ++$ }, STORE => method ($new) { say "$new: ", ++$ } } }; N.text; N.text = 'blah';
Show quoted text
camelia> rakudo-moar b3d816: OUTPUT«fetch: 1␤fetch: 2␤fetch: 3␤fetch: 4␤fetch: 5␤blah: 1␤»
On Sat Oct 31 12:09:05 2015, david.warring wrote: Show quoted text
> Consider the following, which should be a simple and conventional use > of Perl 6 Proxy objects: > > class C { > has $!foo; > method foo is rw { > say "foo"; > $!foo; > } > > has $!bar; > method bar is rw { > Proxy.new( > say "proxy new"; > FETCH => sub ($) { > say "bar fetch"; > $!bar > }, > STORE => sub ($, $v) { > say "bar store"; > $!bar = $v; > }, > ); > } > } > > my $c = C.new; > say "FETCHES"; > $c.foo; > $c.bar; > say "STORES"; > $c.foo++; > $c.bar++; > > OUTPUT: > > FETCHES > foo > proxy new > bar fetch > bar fetch > bar fetch > STORES > foo > proxy new > bar fetch > bar fetch > bar fetch > bar fetch > bar fetch > bar fetch > bar fetch > bar store > > =================== > In the above example, the bar proxy is called 10x whereas foo is > called twice. > > In particular, the proxy FETCH is called 7X to do a simple increment. > > I'm raising this because this is the 'hot path' in projects such as > https://github.com/p6-pdf/perl6-PDF-Tools. > > Would like to see this reduced, if possible.
Download (untitled) / with headers
text/plain 2.6k
On Fri, 22 Apr 2016 21:35:33 -0700, madcap.russo+p6@gmail.com wrote: Show quoted text
> MadcapJake> m: class N { method text { return Proxy.new: FETCH => > MadcapJake> method () { say 'fetch: ', ++$ }, STORE => method ($new) { > MadcapJake> say "$new: ", ++$ } } }; N.text; N.text = 'blah';
> camelia> rakudo-moar b3d816: OUTPUT«fetch: 1␤fetch: 2␤fetch: 3␤fetch: > camelia> 4␤fetch: 5␤blah: 1␤»
> > On Sat Oct 31 12:09:05 2015, david.warring wrote:
> > Consider the following, which should be a simple and conventional use > > of Perl 6 Proxy objects: > > > > class C { > > has $!foo; > > method foo is rw { > > say "foo"; > > $!foo; > > } > > > > has $!bar; > > method bar is rw { > > Proxy.new( > > say "proxy new"; > > FETCH => sub ($) { > > say "bar fetch"; > > $!bar > > }, > > STORE => sub ($, $v) { > > say "bar store"; > > $!bar = $v; > > }, > > ); > > } > > } > > > > my $c = C.new; > > say "FETCHES"; > > $c.foo; > > $c.bar; > > say "STORES"; > > $c.foo++; > > $c.bar++; > > > > OUTPUT: > > > > FETCHES > > foo > > proxy new > > bar fetch > > bar fetch > > bar fetch > > STORES > > foo > > proxy new > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar fetch > > bar store > > > > =================== > > In the above example, the bar proxy is called 10x whereas foo is > > called twice. > > > > In particular, the proxy FETCH is called 7X to do a simple increment. > > > > I'm raising this because this is the 'hot path' in projects such as > > https://github.com/p6-pdf/perl6-PDF-Tools. > > > > Would like to see this reduced, if possible.
Related is a failed attempt to subclass Proxy with a caching version: my class ProxyCache is Proxy { has int $!cached = 0; has $!val; method FETCH { warn "cache fetch"; if $!cached { $!val; } else { $!cached = 1; $!val := callsame; } } method STORE($!val) { warn "cache store"; $!cached = 1; nextsame; } } class C { has $!foo; method foo is rw { say "foo"; $!foo; } has $!bar; method bar is rw { ProxyCache.new( FETCH => sub ($) { say "bar fetch"; $!bar }, STORE => sub ($, $v) { say "bar store"; $!bar = $v; }, ); } } my $c = C.new; say "FETCHES"; $c.foo; $c.bar; say "STORES"; $c.foo++; $c.bar++; But no luck. My caching methods aren't called. Output is unchanged.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org