From dca04b00bc592e8e4b9e36234dccbc1c9531dfe3 Mon Sep 17 00:00:00 2001 From: trizen Date: Sun, 2 Feb 2020 21:44:27 +0200 Subject: [PATCH] - Better performance in Array/Range `each_cons`. --- lib/Sidef/Types/Array/Array.pm | 26 +++++++++++++------- lib/Sidef/Types/Range/Range.pm | 24 +++++++++++++------ scripts/Tests/slices_cons.sf | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/lib/Sidef/Types/Array/Array.pm b/lib/Sidef/Types/Array/Array.pm index 96932bc6c..bbd3f70b9 100644 --- a/lib/Sidef/Types/Array/Array.pm +++ b/lib/Sidef/Types/Array/Array.pm @@ -1398,13 +1398,18 @@ package Sidef::Types::Array::Array { $n = CORE::int($n); my @values; + my $count = 0; foreach my $item (@$self) { - CORE::push(@values, $item); - if (@values == $n) { - my @copy = @values; + if (++$count > $n) { CORE::shift(@values); - $block->run(@copy); + --$count; + } + + CORE::push(@values, $item); + + if ($count == $n) { + $block->run(@values); } } @@ -1420,13 +1425,18 @@ package Sidef::Types::Array::Array { my @result; my @values; + my $count = 0; foreach my $item (@$self) { - CORE::push(@values, $item); - if (@values == $n) { - my @copy = @values; + if (++$count > $n) { CORE::shift(@values); - CORE::push(@result, $block->run(@copy)); + --$count; + } + + CORE::push(@values, $item); + + if ($count == $n) { + CORE::push(@result, $block->run(@values)); } } diff --git a/lib/Sidef/Types/Range/Range.pm b/lib/Sidef/Types/Range/Range.pm index f26dfecf7..84e7709c8 100644 --- a/lib/Sidef/Types/Range/Range.pm +++ b/lib/Sidef/Types/Range/Range.pm @@ -263,15 +263,21 @@ package Sidef::Types::Range::Range { $n > 0 or return $self; my @values; - my $iter = $self->iter; + my $count = 0; + my $iter = $self->iter; for (; ;) { my $value = $iter->run() // last; - push @values, $value; - if (@values == $n) { - my @copy = @values; + + if (++$count > $n) { shift @values; - $block->run(@copy); + --$count; + } + + push @values, $value; + + if ($count == $n) { + $block->run(@values); } } @@ -285,15 +291,19 @@ package Sidef::Types::Range::Range { $n > 0 or return $self; my @values; - my $iter = $self->iter; + my $count = 0; + my $iter = $self->iter; for (; ;) { my $value = $iter->run() // do { $block->run(@values) if @values; return $self; }; + push @values, $value; - if (@values == $n) { + + if (++$count == $n) { + $count = 0; $block->run(splice(@values)); } } diff --git a/scripts/Tests/slices_cons.sf b/scripts/Tests/slices_cons.sf index a8d12ca3f..30c0c409d 100644 --- a/scripts/Tests/slices_cons.sf +++ b/scripts/Tests/slices_cons.sf @@ -26,6 +26,34 @@ do { assert_eq(arr1, [[1, 2, 3], [7, 8, 9], [10]]) } +do { + var arr1 = [] + var arr2 = [] + r.each_slice(5, {|*a| + arr1 << a + }) + a.each_slice(5, {|*a| + arr2 << a + }) + assert_eq(arr1, arr2) + assert_eq(arr1, [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]) +} + +do { + var arr1 = [] + var arr2 = [] + r.each_slice(3, {|*a| + arr1 << a + break if (a == [4,5,6]) + }) + a.each_slice(3, {|*a| + arr2 << a + break if (a == [4,5,6]) + }) + assert_eq(arr1, arr2) + assert_eq(arr1, [[1, 2, 3], [4, 5, 6]]) +} + do { var arr1 = [] var arr2 = [] @@ -41,6 +69,21 @@ do { assert_eq(arr1, [[1, 2, 3], [2, 3, 4], [3, 4, 5], [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10]]) } +do { + var arr1 = [] + var arr2 = [] + r.each_cons(3, {|*a| + arr1 << a + break if (a == [4,5,6]) + }) + a.each_cons(3, {|*a| + arr2 << a + break if (a == [4,5,6]) + }) + assert_eq(arr1, arr2) + assert_eq(arr1, [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]) +} + do { var arr1 = r.map_cons(3, {|*a| next if (a == [4,5,6])