Skip to content

Instantly share code, notes, and snippets.

@lizmat
Last active September 23, 2015 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lizmat/bc7a10a695d361d94e71 to your computer and use it in GitHub Desktop.
Save lizmat/bc7a10a695d361d94e71 to your computer and use it in GitHub Desktop.
Diff for speeding up grep-index(): well, it only speeds up 2x for the push-all case, the pull-one case is only marginally faster
diff --git a/src/core/Any-iterable-methods.pm b/src/core/Any-iterable-methods.pm
index 84c6505..040cf67 100644
--- a/src/core/Any-iterable-methods.pm
+++ b/src/core/Any-iterable-methods.pm
@@ -378,27 +378,87 @@ augment class Any {
}.new(self, $test))
}
+ # This role is not actually used because of RT #126120. Since most of
+ # the speed benefits are lost if we cannot use a native int for $!index,
+ # the contents of this role are copy-pasted for now
+ role GrepIndexer does Iterator {
+ has Mu $!iter;
+ has Mu $!test;
+ has int $!index;
+ method BUILD(\list,\test) {
+ $!iter = as-iterable(list).iterator;
+ $!test := test;
+ $!index = -1;
+ self
+ }
+ method new(\list,\test) { nqp::create(self).BUILD(list,test) }
+ }
+
proto method grep-index(|) is nodal { * }
multi method grep-index(Bool:D $t) is rw {
fail X::Match::Bool.new( type => '.grep-index' );
}
multi method grep-index(Regex:D $test) {
- my int $index = -1;
- self.map: {
- $index = $index+1;
- next unless .match($test);
- nqp::box_i($index,Int);
- };
+ Seq.new(class :: does Iterator { # should be GrepIndexer
+ has Mu $!iter;
+ has Mu $!test;
+ has int $!index;
+ method BUILD(\list,\test) {
+ $!iter = as-iterable(list).iterator;
+ $!test := test;
+ $!index = -1;
+ self
+ }
+ method new(\list,\test) { nqp::create(self).BUILD(list,test) }
+ method pull-one() {
+ my Mu $value;
+ until ($value := $!iter.pull-one) =:= IterationEnd {
+ $!index = $!index + 1;
+ return $!index if $value.match($!test);
+ }
+ IterationEnd
+ }
+ method push-all($target) {
+ my Mu $value;
+ until ($value := $!iter.pull-one) =:= IterationEnd {
+ $!index = $!index + 1;
+ $target.push(+$!index) if $value.match($!test);
+ }
+ IterationEnd
+ }
+ }.new(self, $test))
}
multi method grep-index(Callable:D $test) {
- my int $index = -1;
- self.map: {
- $index = $index + 1;
- next unless $test($_);
- nqp::box_i($index,Int);
- };
+ Seq.new(class :: does Iterator { # should be GrepIndexer
+ has Mu $!iter;
+ has Mu $!test;
+ has int $!index;
+ method BUILD(\list,\test) {
+ $!iter = as-iterable(list).iterator;
+ $!test := test;
+ $!index = -1;
+ self
+ }
+ method new(\list,\test) { nqp::create(self).BUILD(list,test) }
+ method pull-one() {
+ my Mu $value;
+ until ($value := $!iter.pull-one) =:= IterationEnd {
+ $!index = $!index + 1;
+ return $!index if $!test($value);
+ }
+ IterationEnd
+ }
+ method push-all($target) {
+ my Mu $value;
+ until ($value := $!iter.pull-one) =:= IterationEnd {
+ $!index = $!index + 1;
+ $target.push(+$!index) if $!test($value);
+ }
+ IterationEnd
+ }
+ }.new(self, $test))
}
- multi method grep-index(Mu $test) {
+ multi method grep-index(Junction:D $test) {
my int $index = -1;
self.map: {
$index = $index + 1;
@@ -406,6 +466,36 @@ augment class Any {
nqp::box_i($index,Int);
};
}
+ multi method grep-index(Mu $test) {
+ Seq.new(class :: does Iterator { # should be GrepIndexer
+ has Mu $!iter;
+ has Mu $!test;
+ has int $!index;
+ method BUILD(\list,\test) {
+ $!iter = as-iterable(list).iterator;
+ $!test := test;
+ $!index = -1;
+ self
+ }
+ method new(\list,\test) { nqp::create(self).BUILD(list,test) }
+ method pull-one() {
+ my Mu $value;
+ until ($value := $!iter.pull-one) =:= IterationEnd {
+ $!index = $!index + 1;
+ return $!index if $value ~~ $!test;
+ }
+ IterationEnd
+ }
+ method push-all($target) {
+ my Mu $value;
+ until ($value := $!iter.pull-one) =:= IterationEnd {
+ $!index = $!index + 1;
+ $target.push(+$!index) if $value ~~ $!test;
+ }
+ IterationEnd
+ }
+ }.new(self, $test))
+ }
proto method first(|) is nodal { * }
multi method first(Bool:D $t) is rw {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment