From: Robert Klemme [mailto:bob.news@gmx.net]
Since there hasn't been an #inject solution so far...
hmm, is the gateway broken again?
a1.inject(){|s, x| s + a2.map {|y| [x, y]}}
(posted 1 hour ago)
cheers
Simon
From: Robert Klemme [mailto:bob.news@gmx.net]
Since there hasn't been an #inject solution so far...
hmm, is the gateway broken again?
a1.inject(){|s, x| s + a2.map {|y| [x, y]}}
(posted 1 hour ago)
cheers
Simon
Kroeger, Simon (ext) wrote:
From: Robert Klemme [mailto:bob.news@gmx.net]
Since there hasn't been an #inject solution so far...hmm, is the gateway broken again?
a1.inject(){|s, x| s + a2.map {|y| [x, y]}}
(posted 1 hour ago)
No, it's here. Can't tell though whether I just overlooked it or whether
the posting arrived here after I wrote mine.
And note that your version has the disadvantage that you copy s all the
time. Using concat is more efficient. Even if you use that there's an
intermediate array per x value that is dropped again. That's why my
solution just appends two element arrays to the collecting array.
Kind regards
robert
Robert Klemme wrote:
Kroeger, Simon (ext) wrote:
>> From: Robert Klemme [mailto:bob.news@gmx.net]
>> Since there hasn't been an #inject solution so far...
>
> hmm, is the gateway broken again?
>
> a1.inject(){|s, x| s + a2.map {|y| [x, y]}}
>
> (posted 1 hour ago)No, it's here. Can't tell though whether I just overlooked it
or whether the posting arrived here after I wrote mine.And note that your version has the disadvantage [...]
A more significant disadvantage is that you both posted solutions
with equivalent results but for a slightly different problem than
the one posed by the OP
[...] that you copy s all the time.
As did my solution.
Using concat is more efficient.
That's usually safe to say ... but check the b/marks.
That's why my solution just appends two element arrays to
the collecting array.
.... And ends up 3rd out of 3 in the b/mk race
Kind regards
robert
After making the necessary corrections:
#--------------------
require 'benchmark'
include Benchmark
a1 = [1,2,3]
a2 = %w{a b c}
BMN = 50000 # <------ ?whatever?
bm(7) do |bx|
bx.report('d-') { BMN.times { dz = ; a2.each{|s| dz += a1.map {|y| [y, s]}} }}
bx.report('s-') { BMN.times { sk = a2.inject(){|s,x| s + a1.map {|y| [y, x]}} }}
bx.report('r-') { BMN.times { rk = a2.inject(){|r,x| a1.each {|y| r << [y,x]}; r} }}
GC.start ; GC.disable
bx.report('dz') { BMN.times { dz = ; a2.each{|s| dz += a1.map {|y| [y, s]}} }}
GC.start ; GC.disable
bx.report('sk') { BMN.times { sk = a2.inject(){|s,x| s + a1.map {|y| [y, x]}} }}
GC.start ; GC.disable
bx.report('rk') { BMN.times { rk = a2.inject(){|r,x| a1.each {|y| r << [y,x]}; r} }}
end
=begin
user system total real
d- 5.857000 0.000000 5.857000 ( 5.880000)
s- 7.145000 0.000000 7.145000 ( 7.140000)
r- 8.040000 0.000000 8.040000 ( 8.070000)
dz 5.415000 0.000000 5.415000 ( 5.440000)
sk 6.428000 0.000000 6.428000 ( 6.420000)
rk 7.353000 0.000000 7.353000 ( 7.360000)
=end
#--------------------
IMHO - #inject is very useful but I don't see the advantage
of using it to hide an initial x = and
subjecting it to being flung round in circles.
As you can see, it doesn't gain anything, here.
(Not a squabble
daz
daz wrote:
Robert Klemme wrote:
A more significant disadvantage is that you both posted solutions
with equivalent results but for a slightly different problem than
the one posed by the OP
Right. Shouldn't make a difference performance wise though.
That's why my solution just appends two element arrays to
the collecting array.... And ends up 3rd out of 3 in the b/mk race
It depends... (see below)
IMHO - #inject is very useful but I don't see the advantage
of using it to hide an initial x = and
subjecting it to being flung round in circles.As you can see, it doesn't gain anything, here.
(Not a squabble
Your benchmark version crashed on my system because it used too much mem.
IMHO GC times should be *included* because in a real world situation the
time overhead incurred by massive object allocations and deallocations
does in fact influence performance. However, with a modified script I get
17:05:03 [source]: ruby /c/temp/ruby/mappings.rb
Rehearsal ------------------------------------------
dz 5.719000 0.000000 5.719000 ( 5.733000)
dzco 4.984000 0.000000 4.984000 ( 4.988000)
sk 6.891000 0.000000 6.891000 ( 6.959000)
co 6.187000 0.000000 6.187000 ( 6.193000)
rk 5.625000 0.000000 5.625000 ( 5.674000)
rk2 8.938000 0.000000 8.938000 ( 9.017000)
rk3 9.000000 0.000000 9.000000 ( 9.074000)
-------------------------------- total: 47.344000sec
user system total real
dz 5.719000 0.000000 5.719000 ( 5.762000)
dzco 4.921000 0.000000 4.921000 ( 4.997000)
sk 6.875000 0.000000 6.875000 ( 6.918000)
co 6.234000 0.000000 6.234000 ( 6.270000)
rk 5.641000 0.000000 5.641000 ( 5.669000)
rk2 9.078000 0.000000 9.078000 ( 9.137000)
rk3 9.078000 0.000000 9.078000 ( 9.118000)
Interestingly the double inject performs so bad. However the one inject
version is approx as fast as "dz". But the clear winner is *surprise
surprise*
dz = ; a2.each{|s| dz.concat a1.map {|y| [y, s]}}
Would be interesting to see how timings differ for larger arrays...
17:15:43 [source]: ruby /c/temp/ruby/mappings-2.rb
96
Rehearsal ------------------------------------------
dz 3.375000 0.015000 3.390000 ( 3.405000)
dzco 3.485000 0.000000 3.485000 ( 3.532000)
sk 3.453000 0.000000 3.453000 ( 3.478000)
co 3.532000 0.000000 3.532000 ( 3.581000)
rk 3.984000 0.000000 3.984000 ( 4.030000)
rk2 6.594000 0.000000 6.594000 ( 6.619000)
rk3 6.640000 0.000000 6.640000 ( 6.663000)
-------------------------------- total: 31.078000sec
user system total real
dz 3.344000 0.016000 3.360000 ( 3.370000)
dzco 3.157000 0.000000 3.157000 ( 3.192000)
sk 3.422000 0.000000 3.422000 ( 3.429000)
co 3.203000 0.000000 3.203000 ( 3.240000)
rk 3.266000 0.000000 3.266000 ( 3.256000)
rk2 6.562000 0.000000 6.562000 ( 6.576000)
rk3 7.031000 0.000000 7.031000 ( 7.117000)
Differences are much larger. Still I have no clue why the double inject
version is so slow...
Kind regards
robert
mappings.rb (768 Bytes)
mappings-2.rb (818 Bytes)
Robert Klemme wrote:
daz wrote:
> Robert Klemme wrote:dz = ; a2.each{|s| dz.concat a1.map {|y| [y, s]}}
That's enlightening about #concat. When you mentioned
it in reply to Simon, I read it as a reference to your
use of <<. #concat is one of those methods that wasn't
in my vocabulary -- I thought it was an alias for + or
something ... not so.
Most of the time I use << unless it causes unrequired
nesting of arrays, then I go for +. What I hoped I was
doing with + is what #concat does, i.e. splices to the
receiving array without creating a new one.
As Douglas Adams almost wrote:
"Well, that just about wraps it up for Array#+"
Cheers,
daz
+ ....... Concatenation (produces a third array)
concat .. Appends elements (think of as +! bang-method)
push .... <<
<< ...... Append object (alias of push)