Rakudo: .assuming is painfully slow

Created on 10 Jan 2019  Â·  5Comments  Â·  Source: rakudo/rakudo

The Problem

When creating a function using .assuming, the performance of the function is severely impaired. For example,

my $*x = 0; 
my &a = sub ($y) { $*x += $y };
a(1) for ^100000;

runs much slower (takes about 30x the time) than

my $*x = 0; 
my &a = sub ($y) { $*x += $y };
my &b = &a.assuming(1);
b for ^100000;

Expected Behavior

The performance should be approximately the same.

Actual Behavior

The speed is much slower.

Steps to Reproduce

The following code reproduces the issue well (and shows comparison to other similar code that is more performant)

my $*z = 0;
my $y = 100000;

my &a = sub { $*z++ };
my &b = sub { $*z += 1 };
my &c = sub ($x) { $*z += $x };
my &d = &c.assuming(1);
my @e = 1 xx $y;

{
	print "  ++ Increment: ";
	a for ^$y;
	say now - ENTER now;
}

{
	print "+= 1 Increment: ";
	b for ^$y;
	say now - ENTER now;
}

{
	print "  Explicit arg: ";
	c(1) for ^$y;
	say now - ENTER now;
}

{
	print "   Assumed arg: ";
	d for ^$y;
	say now - ENTER now;
}

{
	print "Ext stored arg: ";
	c(@e[$_]) for ^$y;
	say now - ENTER now;
}

The output of the above code is:

  ++ Increment: 0.05643606
+= 1 Increment: 0.09443329
  Explicit arg: 0.095659
   Assumed arg: 6.9337546
Ext stored arg: 0.286605

Try it online!

Environment

  • Operating system: mac OS Mojave (10.14)
  • Compiler version (perl6 -v):
    This is Rakudo version 2018.12 built on MoarVM version 2018.12
    implementing Perl 6.d.
performance

All 5 comments

Here's a flame graph of a version of the "steps to reproduce" script. On the far left you can see a deep spike (it goes on for many more lines) which is the compiler creating the code for the assuming stuff, the "..." blocks are the other blocks, and the entire rest is running the code generated by .assuming.

A lot of the functions are related to signature binding and capture unpacking and slurpies and all that.

selection_117

I'd guess that currently .assuming doesn't check if the signature of the sub in question has no slurpies, because otherwise a much simpler signature could probably be made? Haven't looked at the code yet.

The code of .assuming has been an approach to get it working. Brian Julin (aka skids) developed it originally in the summer of 2015. From that time I remember he had a tough time to get all of the features implemented, and didn't get a lot of support from other core members. Specifically some MOP functions appear to be insufficient or insufficiently documented, so that EVAL was needed in at least some of the cases to get things working. Having looked at the code several times myself, I'd say it's ready for a refactor, provided we have enough testing for it.

IIRC part of the problem was making the signature of the new routine right. Providing some mechanism to alter the signature of a routine might take it most of the way.

FWIW, I'm working on a sensible interface for Signature.new

First stab at making Parameter a first class citizen: 3d3578b605

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Altai-man picture Altai-man  Â·  3Comments

zoffixznet picture zoffixznet  Â·  3Comments

AlexDaniel picture AlexDaniel  Â·  5Comments

Altai-man picture Altai-man  Â·  3Comments

gfldex picture gfldex  Â·  5Comments