Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Perl 6 and performance

by moritz (Cardinal)
on Feb 09, 2012 at 17:26 UTC ( [id://952791]=note: print w/replies, xml ) Need Help??


in reply to Perl 6 and performance

You've indeed hit a regression in Rakudo here. Let me explain it.

1/$_**2 produces a Rat object in Perl 6 if $_ is an integer (it is here). That is, it's a rational number that stores the numerator and denominator as integers. Thus $s is als a Rat, and the way that $s is built makes the denominator grow very fast.

Since newest Rakudo has bigint support, the integers can now grow larger than 64bit, and the growing size of the integers causes the O(nē) slowness you observed.

The specification says that once the denominator exceeds 2 ** 64 128, the arithmetic ops are supposed to fall back to floating point numbers to avoid such cases of pathological performance. Rakudo hasn't implemented that part yet, hence the regression.

If you use floating point numbers to begin with, you'll get:

$ time ./perl6 -e 'my $s; for 1..10000 {$s+=1e0/$_**2};say $s' 1.64483407184807 real 0m1.659s user 0m1.360s sys 0m0.200s

niecza correctly implements the fallback to floating point values, and yields the correct result (in 3s on a different machine of mine; it's usually slow to compile stuff, but faster at run time).

I've already started a branch to fix the Rat arithmetic issues (branch 'Rational' on github), and I'll try to make it work before the next Star release; I can't promise it though.

P.S. I'm sad to see that perlmonks is slowly becoming more like reddit, where problems are met with rancorousness instead of being discussed on a technical level.

UPDATE (2012-02-13): I've fixed Rakudo to fall back to Num if the denominator exceeds 2**64, so now you get:

$ time ./perl6 -e 'my $s; for 1..1000 {$s+=1/$_**2};say $s' 1.64393456668156 real 0m1.341s user 0m1.240s sys 0m0.096s

You can get this fix by using the latest development revision from git, or wait for the next release. Thanks again for your feedback.

Second update: when running up to 10_000 it takes 2.8s on my machine, so while still a big step away from perl 5 speed, it's faster than your previous measurements.

Replies are listed 'Best First'.
Re^2: Perl 6 and performance
by talexb (Chancellor) on Feb 09, 2012 at 17:33 UTC
      P.S. I'm sad to see that perlmonks is slowly becoming more like reddit, where problems are met with rancorousness instead of being discussed on a technical level.

    I think the peevishness is a result of hype exhaustion on the topic of Perl6. I'm thrilled that a barrel-full of very bright people are working on the next generation of Perl, but I'll happily wait till it's cooked, and I'll continue to happily use the excellent Perl5 in the meantime. It's worked very well for me for the last 15 years, and it's still very much alive.

    And, as the kids say, "It's all good."

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      My point of view is that Perl6 is not so much a successor to Perl5 but rather an alternative to it. To that end it might have been preferable not to call it Perl6 but maybe something like PerlVM that would indicate that it takes a radically different approach to "classic" Perl.

      If/when Perl6 does reach release-level maturity it probably won't supplant Perl5. The two can quite happily co-exist as different implementations which share (most of) a common syntax. At that point we can all choose the right tool for the job at hand.

      Just my tuppence.

      Update: It's now October 2019 and "Perl6" is now "Raku" so that, belatedly but thankfully, solves the naming problem. The syntax is probably more divergent from Perl than I anticipated but the two languages (and communities) can now co-exist and provide two different tools for every programmer.

Re^2: Perl 6 and performance
by kikuchiyo (Hermit) on Feb 09, 2012 at 19:32 UTC

    Thank you for the detailed answer. It indeed makes the cause of the problem clear.

    For me, it's more natural to write a floating point constant one as 1.0, however, that doesn't work. And this won't even run:

    time ./perl6 -e 'my $s; for 1..10000 {$s+=1./$_**2};say $s' ===SORRY!=== Unable to parse blockoid, couldn't find final '}' at line 2

    I've also tried to explicitly declare the loop variable as a floating point:

    ./perl6 -e 'my $s;my Num $i;for 1..10000 -> $i {$s+=1/$i**2};say $s'

    This has no effect, as can be seen from the following:

    ./perl6 -e 'my Num $s;my Num $i;for 1..10000 -> $i {$s+=1/$i**2};say $ +s' Type check failed in assignment to '$s'; expected 'Num' but got 'Rat' in method reify at src/gen/CORE.setting:4471 in method reify at src/gen/CORE.setting:4376 in method reify at src/gen/CORE.setting:4376 in method gimme at src/gen/CORE.setting:4740 in method eager at src/gen/CORE.setting:4715 in method eager at src/gen/CORE.setting:1028 in sub eager at src/gen/CORE.setting:5000

    Does this mean that even though I declare $i as a Num, it's still an integer when used as a loop variable? Is it because the .. operator supplies integers?

    P.S. I'm sad to see that perlmonks is slowly becoming more like reddit, where problems are met with rancorousness instead of being discussed on a technical level.

    I admit that I posed the original question in a slightly more trollish way than necessary, and I apologize for the inconvenience I might have created. I didn't intend to denigrate the effort of the Perl 6 developers - an effort which is nothing short of heroic.

    However, I do think that the problems with the current state of Perl 6 go way beyond the technical level, and pretending that these problems can be treated at the mere technical level is an attitude that does more harm than good on the long term.

      To clarify things, 1. is not a valid number in Perl 6. 1.0 is a Rat, 1e0 or 1.0e0 are Num.

      I've also tried to explicitly declare the loop variable as a floating point:

      There are two issues with it. The first is that you don't declare the loop variable to be a Num, but an outer variable of the same name. In -> $i { ... } the part between the arrow and the block is a signature, which declares a new variable. So it's like writing

      my Num $i; sub ($i) { # new $i here }

      A way to fix that is writing -> Num $i { }, but then you get a type check failure because 1..1000 indeed produces Ints, not Nums. So either you coerce to Num somewhere (for example $i.Num ** 2), or you write the range as 1e0 .. 1e3.

      I admit that I posed the original question in a slightly more trollish way than necessary, and I apologize for the inconvenience I might have created. I didn't intend to denigrate the effort of the Perl 6 developers - an effort which is nothing short of heroic.

      My side remark was more about _foo's trolling, not about your original question, which I think is 100% valid, and a good bug report at that. Sorry if that came out wrong on my part. User feedback like yours is what we need, and one of the reasons for making the star releases in the first place.

        To clarify things, 1. is not a valid number in Perl 6. 1.0 is a Rat, 1e0 or 1.0e0 are Num.

        This is news to me. In most languages 1.0 is the syntax used to denote floating point constants.

        ...I am aware that Perl 6 is not most languages, but for people coming from those languages, this feature will be somewhat surprising.

        A way to fix that is writing -> Num $i { }, but then you get a type check failure because 1..1000 indeed produces Ints, not Nums. So either you coerce to Num somewhere (for example $i.Num ** 2), or you write the range as 1e0 .. 1e3.
        Excellent. However:
        ./perl6 -e 'my Num $s;for 1e0..1e3 -> Num $i {$s+=1e0/$i**2};say $s' Nominal type check failed for parameter '$i'; expected Num but got Int + instead
        User feedback like yours is what we need, and one of the reasons for making the star releases in the first place.

        Glad to have been of help then. By the way, the performance increase is noticeable in the new release, and I guess it will only get better, and the effect of further optimizations will be compounded, as Rakudo itself is mostly written in Perl 6.

        About 1.6 orders of magnitude of performance increase down, 2.6 to get to the level of Perl 5, or 1.6 to overtake Ruby. :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://952791]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-20 01:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found