Hello…
What’s the most efficient way for
puts [1,2,3,4,5,6,7,8,9,10].collect{ |x| next if x % 2 == 0; x+10 }.compact
or
puts [1,2,3,4,5,6,7,8,9,10].collect!{ |x| next if x % 2 == 0; x+10 }.compact!
Or:
I want to iterate over all array elements, process them, decide
whether the result is any good, and keep only the good ones.
It’s ok doing that by chaining collect+compact, but I ponder this must
be slow/inefficient for array with xxxxx elements.
I read Array and Enumerable docs, have I missed something[1] or does
a straight “collect everything but nil” function not exist?
Martin
[1]
(it’s already past 3am but I remember searching the same thing sometime ago)
This is perhaps better:
[1,2,3,4,5,6,7,8,9,10].inject() { |s, x| x % 2 == 0 ? s : s << x + 10 }
At least the created temporary array is smaller.
···
On 2004-04-21 10:29:07 +0900, Martin Pirker wrote:
puts [1,2,3,4,5,6,7,8,9,10].collect{ |x| next if x % 2 == 0; x+10 }.compact
or
puts [1,2,3,4,5,6,7,8,9,10].collect!{ |x| next if x % 2 == 0; x+10 }.compact!
–
c, s, x = gets, c[0, 2].to_i, “dsfd;kfoA,.iyewrkldJKDHSUB”
puts (1…(c.size / 2)).inject(“”) do |p, i|
p << (c[2 * i, 2].to_i(16) ^ x[(s += 1) && s -1])
end
Hello…
What’s the most efficient way for
puts [1,2,3,4,5,6,7,8,9,10].collect{ |x| next if x % 2 == 0; x+10 }.compact
or
puts [1,2,3,4,5,6,7,8,9,10].collect!{ |x| next if x % 2 == 0; x+10 }.compact!
Or:
I want to iterate over all array elements, process them, decide
whether the result is any good, and keep only the good ones.
It’s ok doing that by chaining collect+compact, but I ponder this must
be slow/inefficient for array with xxxxx elements.
doesn’t seem to make much difference:
~ > time ruby -e ‘(1…ARGV.shift.to_i).to_a.collect{|x| next if x % 2 == 0; x+10 }.compact’ 1048576
real 0m1.496s
user 0m1.480s
sys 0m0.020s
~ > time ruby -e ‘(1…ARGV.shift.to_i).to_a.collect!{ |x| next if x % 2 == 0; x+10 }.compact!’ 1048576
real 0m1.396s
user 0m1.390s
sys 0m0.000s
suprising.
I read Array and Enumerable docs, have I missed something[1] or does
a straight “collect everything but nil” function not exist?
Martin
[1]
(it’s already past 3am but I remember searching the same thing sometime ago)
-a
···
On 21 Apr 2004, Martin Pirker wrote:
===============================================================================
EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================
Martin Pirker wrote:
Hello…
What’s the most efficient way for
puts [1,2,3,4,5,6,7,8,9,10].collect{ |x| next if x % 2 == 0; x+10 }.compact
or
puts [1,2,3,4,5,6,7,8,9,10].collect!{ |x| next if x % 2 == 0; x+10 }.compact!
Hmmm… not sure I can offer any help in increasing performance, but it
seems perhaps the following is a bit cleaner:
puts (1…10).to_a.collect{ |x| x + 10 if x % 2 == 0 }.compact
try yourself:
map!+compact! 11
0.141000 0.000000 0.141000 ( 0.141000)
map+compact 21
0.078000 0.000000 0.078000 ( 0.078000)
inject 21
0.235000 0.000000 0.235000 ( 0.234000)
external 21
0.093000 0.000000 0.093000 ( 0.094000)
external for 21
0.094000 0.000000 0.094000 ( 0.094000)
code
require ‘benchmark’
Z=(1…100000).to_a
Benchmark.bm(10) do |b|
b.report 'map!+compact! ’ do
ary=Z.map!{ |x| next if x % 2 == 0; x+10 }.compact!
p ary[0]
end
b.report 'map+compact ’ do
ary=Z.map{ |x| next if x % 2 == 0; x+10 }.compact
p ary[0]
end
b.report 'inject ’ do
ary=Z.inject() { |s, x| x % 2 == 0 ? s : s << x + 10 }
p ary[0]
end
b.report 'external ’ do
ary=
Z.each {|x| ary<<(x+10) unless x%2==0 }
p ary[0]
end
b.report 'external for ’ do
ary=
for i in Z
ary<<(i+10) unless i%2==0
end
p ary[0]
end
end
···
il 21 Apr 2004 01:27:07 GMT, Martin Pirker nospam@sbox.tu-graz.ac.at ha scritto::
Hello…
What’s the most efficient way for
puts [1,2,3,4,5,6,7,8,9,10].collect{ |x| next if x % 2 == 0; x+10 }.compact
or
puts [1,2,3,4,5,6,7,8,9,10].collect!{ |x| next if x % 2 == 0; x+10 }.compact!
Martin Pirker wrote:
I read Array and Enumerable docs, have I missed something[1] or does
a straight “collect everything but nil” function not exist?
The function select collects everything but false elements, the function
reject does the opposite. I am surprised that this did not come up as
the first answer:
(insert this into code posted earlier on thread)
b.report ‘select+collect’ do
~ ary= Z.select{ |x| x%2 != 0 }.collect{|x| x+10}
~ p ary[0]
~ end
~ b.report ‘reject+collect’ do
~ ary= Z.reject{ |x| x%2 == 0 }.collect{|x| x+10}
~ p ary[0]
~ end
Performance comparison yields:
~ user system total real
map!+compact!
~ 1.202000 0.000000 1.202000 ( 1.422000)
map+compact
~ 0.651000 0.010000 0.661000 ( 0.711000)
inject
~ 5.378000 0.000000 5.378000 ( 5.608000)
external
~ 0.781000 0.000000 0.781000 ( 0.781000)
external for
~ 0.741000 0.000000 0.741000 ( 0.741000)
select+collect
~ 0.871000 0.000000 0.871000 ( 0.872000)
reject+collect
~ 0.831000 0.000000 0.831000 ( 0.831000)
for a million elements. Ranking as follows (from this one test):
map+compact
external for
external
reject+collect
select+collect
map!+compact!
inject
I take the following lessons home:
-
- map/collect is fast, since it preallocates arrays.
-
- external for is fast, no allocating of blocks
-
- inject is evil because of its implementation
ruby 1.8.1 (2004-01-27) [i386-mswin32] btw.
Anyone more explanations ?
kaspar - code philosopher
- – stolen off the net –
A rock pile ceases to be a rock pile the moment a single man
contemplates it, bearing within him the image of a cathedral.
~ – Antoine de Saint-Exupery