Skip Menu |
Report information
Id: 125344
Status: resolved
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: rob [at] hoelz.ro
Cc:
AdminCc:

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



Subject: Int..Whatever ranges are slow (~20 times slower than Int..Int)
Download (untitled) / with headers
text/plain 177b
Let's say I have an array where @array.end == $end. Using @array[0..$end] is about 20 times faster than @array[0..*]. I have attached an example script that demonstrates this.
Subject: bench.p6
Download bench.p6
application/octet-stream 302b

Message body not shown because it is not plain text.

From: Elizabeth Mattijsen <liz [...] dijkmat.nl>
To: "Rob Hoelz (via RT)" <perl6-bugs-followup [...] perl.org>
Subject: Re: [perl #125344] Int..Whatever ranges are slow (~20 times slower than Int..Int)
Date: Sun, 7 Jun 2015 00:25:09 -0600
Download (untitled) / with headers
text/plain 677b
Show quoted text
> On 06 Jun 2015, at 21:24, Rob Hoelz (via RT) <perl6-bugs-followup@perl.org> wrote: > > # New Ticket Created by Rob Hoelz > # Please include the string: [perl #125344] > # in the subject line of all future correspondence about this issue. > # <URL: https://rt.perl.org/Ticket/Display.html?id=125344 > > > > Let's say I have an array where @array.end == $end. Using @array[0..$end] is about 20 times faster than @array[0..*]. I have attached an example script that demonstrates this.<bench.p6>
If it’s the whole array that you want, have you considered using the zen slice? That is still a lot faster than [0..$end]. Looking at why the * case is so slow. Liz
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 949b
On Sat, 06 Jun 2015 20:24:32 -0700, rob@hoelz.ro wrote: Show quoted text
> Let's say I have an array where @array.end == $end. Using > @array[0..$end] is about 20 times faster than @array[0..*]. I have > attached an example script that demonstrates this.
Thanks for the report, however there's no issue with the compiler here. You're comparing different behaviours: 0..* is a lazy Iterable, so extra checks are performed to stop iteration of indices once an end is reached. If you make 0..$end lazy, so the same checks are performed, the perf difference actually gives 0..* is small edge (likely due to optimized Ranger.iterator) <Zoffix__> m: my @array = 1..1000; my $end = @array.end; for ^500 { $ = @array[0..*] }; say now - INIT now <camelia> rakudo-moar 39d50a: OUTPUT: «3.050471␤» <Zoffix__> m: my @array = 1..1000; my $end = @array.end; for ^500 { $ = @array[lazy 0..$end] }; say now - INIT now <camelia> rakudo-moar 39d50a: OUTPUT: «3.3454447␤»
So-o. Zoffix insists that everything is correct here, and perhaps it is so. That being said, I don't quite understand why it can't be done. Maybe somebody else can take a look also. Here's my logic:

So if you have

@array[0..@array.end]

and

@array[0..*]

Would we get identical results from both of these snippets? I guess we should. But if it is so, why can't it just pretend that * is @array.end? If I understand correctly, the range object is right there for inspection, so everything should be possible.

Zoffix++ pointed out ( https://irclog.perlgeek.de/perl6/2017-10-08#i_15273200 ) that 0..* will stop at the first hole, but there's a ticket for that: https://rt.perl.org/Ticket/Display.html?id=127573

So assuming that the bug is eventually resolved and both @array[0..@array.end] and @array[0..*] start giving exactly the same result in all cases, why can't it be done? And if these two snippets give different results, then what are these difference? This would be some good doc material.

If there's a chance that it can be done, let's keep this open. The difference is dramatic and [0..*] is very common in normal code.

On 2017-10-07 21:44:40, cpan@zoffix.com wrote:
Show quoted text
> On Sat, 06 Jun 2015 20:24:32 -0700, rob@hoelz.ro wrote:
> > Let's say I have an array where @array.end == $end. Using
> > @array[0..$end] is about 20 times faster than @array[0..*]. I have
> > attached an example script that demonstrates this.
>
>
> Thanks for the report, however there's no issue with the compiler
> here.
>
> You're comparing different behaviours: 0..* is a lazy Iterable, so
> extra checks
> are performed to stop iteration of indices once an end is reached. If
> you make 0..$end lazy,
> so the same checks are performed, the perf difference actually gives
> 0..* is small edge (likely due
> to optimized Ranger.iterator)
>
> <Zoffix__> m: my @array = 1..1000; my $end = @array.end; for ^500 { $
> = @array[0..*] }; say now - INIT now
> <camelia> rakudo-moar 39d50a: OUTPUT: «3.050471␤»
> <Zoffix__> m: my @array = 1..1000; my $end = @array.end; for ^500 { $
> = @array[lazy 0..$end] }; say now - INIT now
> <camelia> rakudo-moar 39d50a: OUTPUT: «3.3454447␤»


RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 181b
On Sat, 07 Oct 2017 22:19:46 -0700, alex.jakimenko@gmail.com wrote: Show quoted text
> why can't it just pretend that * is @array.end?
Done now in https://github.com/rakudo/rakudo/commit/456358e3c3


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