Skip to content

Commit

Permalink
unify the code for filter methods (and speed up #reject!)
Browse files Browse the repository at this point in the history
the worst case for `Array#reject!` (i.e. a proc always returning `true`)
is at least 5x worse than the worst case for `Array#select!` (proc
always returning `false`)

this commit unifies these implementations and inlines the (effective)
call of `#select!` in `#keep_if` and `#reject!` in `#delete_if`
  • Loading branch information
leviongit committed Apr 13, 2024
1 parent d761561 commit 81bb520
Showing 1 changed file with 28 additions and 26 deletions.
54 changes: 28 additions & 26 deletions mrbgems/mruby-array-ext/mrblib/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,15 +467,16 @@ def fill(arg0=nil, arg1=nil, arg2=nil, &block)
def delete_if(&block)
return to_enum :delete_if unless block

result = []
idx = 0
while idx < self.size do
if block.call(self[idx])
self.delete_at(idx)
else
idx += 1
end
len = size
while idx < len
elem = self[idx]
result << elem unless block.call(elem)
idx += 1
end
self

self.replace(result)
end

##
Expand All @@ -496,20 +497,18 @@ def delete_if(&block)
def reject!(&block)
return to_enum :reject! unless block

len = self.size
result = []
idx = 0
while idx < self.size do
if block.call(self[idx])
self.delete_at(idx)
else
idx += 1
end
end
if self.size == len
nil
else
self
len = size
while idx < len
elem = self[idx]
result << elem unless block.call(elem)
idx += 1
end

return nil if len == result.size

self.replace(result)
end

##
Expand Down Expand Up @@ -658,15 +657,16 @@ def bsearch_index(&block)
def keep_if(&block)
return to_enum :keep_if unless block

result = []
idx = 0
while idx < self.size do
if block.call(self[idx])
idx += 1
else
self.delete_at(idx)
end
len = size
while idx < len
elem = self[idx]
result << elem if block.call(elem)
idx += 1
end
self

self.replace(result)
end

##
Expand Down Expand Up @@ -694,7 +694,9 @@ def select!(&block)
result << elem if block.call(elem)
idx += 1
end

return nil if len == result.size

self.replace(result)
end

Expand Down

0 comments on commit 81bb520

Please sign in to comment.