Parallel Assignments and Elegance/Complexity Ratio.

Discussion in 'Ruby' started by Kedar Mhaswade, Jan 11, 2011.

  1. In SICP, I read that "Programs should be written for people to read, and
    only incidentally for machines to execute".

    While reading David/Matz book, I stumbled upon parallel assignments and
    I thought the language was trying to be too flexible (adding complexity,
    at least for a newcomer). My head soon started
    spinning (when it reached a, (b, (c,d)) = 1, [2, [3, 4]] I was
    exhausted).

    My experience is recorded here:
    https://docs1.google.com/document/d/1zpHvfO4be3UvjaxU7L5gEPXFMENcMmEz9qqIcecEzOg/edit?hl=en#

    Summary is, I should only spend time learning
    - x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
    - x, y = y, x (# => swap x and y)

    I gather that this might be a matter of taste and style, but are other
    variants used by community?

    Thank you,
    Kedar

    --
    Posted via http://www.ruby-forum.com/.
    Kedar Mhaswade, Jan 11, 2011
    #1
    1. Advertising

  2. On Tue, Jan 11, 2011 at 3:29 PM, Kedar Mhaswade
    <> wrote:
    > In SICP, I read that "Programs should be written for people to read, and
    > only incidentally for machines to execute".
    >
    > While reading David/Matz book, I stumbled upon parallel assignments and
    > I thought the language was trying to be too flexible (adding complexity,
    > at least for a newcomer). My head soon started
    > spinning (when it reached a, (b, (c,d)) = 1, [2, [3, 4]] I was
    > exhausted).
    >
    > My experience is recorded here:
    > https://docs1.google.com/document/d/1zpHvfO4be3UvjaxU7L5gEPXFMENcMmEz9qqIcecEzOg/edit?hl=en#
    >
    > Summary is, I should only spend time learning
    > - x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
    > - x, y = y, x (# => swap x and y)
    >
    > I gather that this might be a matter of taste and style, but are other
    > variants used by community?


    Just today I used

    def []=(*idx, val)
    index_check(idx)
    @data[idx] = val
    end

    https://gist.github.com/772827

    See also thread "Nooby question : multidimensional arrays.".

    I find the pattern matching _very_ elegant. This also comes in handy
    in situations like this:

    irb(main):001:0> a = Array.new(10) { [rand(10), rand(10)] }
    => [[2, 3], [7, 8], [4, 0], [4, 6], [5, 2], [9, 9], [4, 2], [8, 5],
    [2, 6], [5, 9]]
    irb(main):002:0> a.sort {|(a1,a2),(b1,b2)| x = a2 <=> b2; x == 0 ? a1
    <=> b1 : x}
    => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
    [5, 9], [9, 9]]

    Although in this particular case you could also use

    irb(main):004:0> a.sort_by {|arr| arr.reverse}
    => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
    [5, 9], [9, 9]]
    irb(main):005:0> a.sort_by {|x, y| [y, x]}
    => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
    [5, 9], [9, 9]]

    Generally I'd say I don't use it overly often but when I use it it is
    really handy. With #inject it's also useful if you iterate through a
    collection of Arrays of known equal length:

    irb(main):006:0> a.inject(0) {|s,(x,y)| s + x + y}
    => 100

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Jan 11, 2011
    #2
    1. Advertising

  3. Robert Klemme wrote in post #973945:
    > On Tue, Jan 11, 2011 at 3:29 PM, Kedar Mhaswade
    > <> wrote:
    >>

    >

    https://docs1.google.com/document/d/1zpHvfO4be3UvjaxU7L5gEPXFMENcMmEz9qqIcecEzOg/edit?hl=en#
    >>
    >> Summary is, I should only spend time learning
    >> - x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
    >> - x, y = y, x (# => swap x and y)
    >>
    >> I gather that this might be a matter of taste and style, but are other
    >> variants used by community?

    >
    > Just today I used
    >
    > def []=(*idx, val)
    > index_check(idx)
    > @data[idx] = val
    > end
    >
    > https://gist.github.com/772827
    >
    > See also thread "Nooby question : multidimensional arrays.".
    >
    > I find the pattern matching _very_ elegant. This also comes in handy
    > in situations like this:


    Maybe I am not understanding it, but I thought that elegance is because
    of splat operator (which I am sure I like). My gripe is about various
    forms of parallel assignment and semantic/syntactic complexity because
    of that. Or are you saying that once you say you need splat operator,
    all this complexity is inevitable (of course, I can work around it by
    not using it, but then how do you all use it?)

    -Kedar

    >
    > irb(main):001:0> a = Array.new(10) { [rand(10), rand(10)] }
    > => [[2, 3], [7, 8], [4, 0], [4, 6], [5, 2], [9, 9], [4, 2], [8, 5],
    > [2, 6], [5, 9]]
    > irb(main):002:0> a.sort {|(a1,a2),(b1,b2)| x = a2 <=> b2; x == 0 ? a1
    > <=> b1 : x}
    > => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
    > [5, 9], [9, 9]]
    >
    > Although in this particular case you could also use
    >
    > irb(main):004:0> a.sort_by {|arr| arr.reverse}
    > => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
    > [5, 9], [9, 9]]
    > irb(main):005:0> a.sort_by {|x, y| [y, x]}
    > => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
    > [5, 9], [9, 9]]
    >
    > Generally I'd say I don't use it overly often but when I use it it is
    > really handy. With #inject it's also useful if you iterate through a
    > collection of Arrays of known equal length:
    >
    > irb(main):006:0> a.inject(0) {|s,(x,y)| s + x + y}
    > => 100
    >
    > Kind regards
    >
    > robert


    --
    Posted via http://www.ruby-forum.com/.
    Kedar Mhaswade, Jan 11, 2011
    #3
  4. Kedar Mhaswade

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Tue, Jan 11, 2011 at 8:29 AM, Kedar Mhaswade <>wrote:

    > In SICP, I read that "Programs should be written for people to read, and
    > only incidentally for machines to execute".
    >
    > While reading David/Matz book, I stumbled upon parallel assignments and
    > I thought the language was trying to be too flexible (adding complexity,
    > at least for a newcomer). My head soon started
    > spinning (when it reached a, (b, (c,d)) = 1, [2, [3, 4]] I was
    > exhausted).
    >
    > My experience is recorded here:
    >
    > https://docs1.google.com/document/d/1zpHvfO4be3UvjaxU7L5gEPXFMENcMmEz9qqIcecEzOg/edit?hl=en#
    >
    > Summary is, I should only spend time learning
    > - x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
    > - x, y = y, x (# => swap x and y)
    >
    > I gather that this might be a matter of taste and style, but are other
    > variants used by community?
    >
    > Thank you,
    > Kedar
    >
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >

    I don't use it very often, but when I do, it usually makes an elegant
    solution. I think part of the reason it doesn't seem that way is because you
    are playing with it in too sterile of an environment. For example, you rate
    "x, (y, (z, a))=[1, [2, [3, 4]]]" as lowest, suggesting it is equivalent to
    "x=1;y=2;z=3;a=4" but this is not true. If you are actually assigning with
    literals, you would, of course, use the equivalent way, but if your data
    comes in as nested arrays, then you can't assign like that, instead you have
    to do something like this:

    def parallel(values)
    x, (y, (z, a))=values
    [x,y,z,a]
    end
    def alternative(values)
    x = values.shift
    values = values.shift
    y = values.shift
    values = values.shift
    z = values.shift
    a = values.shift
    [x,y,z,a]
    end
    parallel [1, [2, [3, 4]]] # => [1, 2, 3, 4]
    alternative [1, [2, [3, 4]]] # => [1, 2, 3, 4]




    Now, I don't normally store data like that, so I haven't ever done anything
    quite that fancy, but I use arrays on the RHS on occasion. It might look
    something like this (though I don't normally store my data like this, either
    -- it's really hard to think of a decent example!).

    $stdin = DATA
    while input = gets
    name , num = input.split
    puts "#{name.capitalize}'s favourite number is #{num}"
    end
    __END__
    josh 12
    bill 42
    sally 13
    ned 99
    clara 1000000



    The alternative of
    name , num = input.split
    is
    values = input.split
    name = values.shift
    num = values

    I consider the former to be much more elegant as it avoids a temporary
    variable.
    Josh Cheek, Jan 11, 2011
    #4
  5. > literals, you would, of course, use the equivalent way, but if your data
    > comes in as nested arrays, then you can't assign like that, instead you
    > have
    > to do something like this:
    >
    > def parallel(values)
    > x, (y, (z, a))=values
    > [x,y,z,a]
    > end
    > def alternative(values)
    > x = values.shift
    > values = values.shift
    > y = values.shift
    > values = values.shift
    > z = values.shift
    > a = values.shift
    > [x,y,z,a]
    > end
    > parallel [1, [2, [3, 4]]] # => [1, 2, 3, 4]
    > alternative [1, [2, [3, 4]]] # => [1, 2, 3, 4]
    >
    > Now, I don't normally store data like that, so I haven't ever done
    > anything
    > quite that fancy, but I use arrays on the RHS on occasion. It might look
    > something like this (though I don't normally store my data like this,
    > either
    > -- it's really hard to think of a decent example!).


    Thank you for sharing the use case. In this case, it helps. But like you
    said, it seems like an answer in search of a question.

    >
    > $stdin = DATA
    > while input = gets
    > name , num = input.split
    > puts "#{name.capitalize}'s favourite number is #{num}"
    > end
    > ...
    >
    > The alternative of
    > name , num = input.split
    > is
    > values = input.split
    > name = values.shift
    > num = values
    >
    > I consider the former to be much more elegant as it avoids a temporary
    > variable.

    This however is already covered by me as the first case (with HIGH
    elegance rating) since you are expecting the line to contain exactly two
    strings (and if it is not so, it's an exceptional situation) and hence
    the (expected) number of lvalues = number of rvalues. I do
    like/understand such application of parallel assignment.

    Thanks, again!

    --
    Posted via http://www.ruby-forum.com/.
    Kedar Mhaswade, Jan 11, 2011
    #5
  6. Kedar Mhaswade

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Tue, Jan 11, 2011 at 2:29 PM, Kedar Mhaswade <>wrote:

    > > variable.
    > > I consider the former to be much more elegant as it avoids a temporary

    > This however is already covered by me as the first case (with HIGH
    > elegance rating) since you are expecting the line to contain exactly two
    > strings (and if it is not so, it's an exceptional situation) and hence
    > the (expected) number of lvalues = number of rvalues. I do
    > like/understand such application of parallel assignment.
    >
    >

    Sorry, I don't understand. In this example, the rhs values are contained in
    an Array, which you consider low elegance, in your first example the rhs
    values are discrete. I don't see how they are the same, I think this is an
    instance of your "x, y, z = [1, 2, 3]", which you consider to be low
    elegance.
    Josh Cheek, Jan 11, 2011
    #6
  7. > Sorry, I don't understand. In this example, the rhs values are contained
    > in
    > an Array, which you consider low elegance, in your first example the rhs
    > values are discrete. I don't see how they are the same, I think this is
    > an
    > instance of your "x, y, z = [1, 2, 3]", which you consider to be low
    > elegance.


    Ah, you are right. I stand corrected. Thanks.

    --
    Posted via http://www.ruby-forum.com/.
    Kedar Mhaswade, Jan 11, 2011
    #7
  8. On Tue, Jan 11, 2011 at 7:54 PM, Kedar Mhaswade
    <> wrote:
    > Robert Klemme wrote in post #973945:
    >> On Tue, Jan 11, 2011 at 3:29 PM, Kedar Mhaswade
    >> <> wrote:
    >>>

    >>

    > https://docs1.google.com/document/d/1zpHvfO4be3UvjaxU7L5gEPXFMENcMmEz9qqI=

    cecEzOg/edit?hl=3Den#
    >>>
    >>> Summary is, I should only spend time learning
    >>> - x, y, z =3D 1, 2, 3 (# =3D> x=3D1, y=3D1, z=3D3), and
    >>> - x, y =3D y, x (# =3D> swap x and y)
    >>>
    >>> I gather that this might be a matter of taste and style, but are other
    >>> variants used by community?

    >>
    >> Just today I used
    >>
    >> =A0 def []=3D(*idx, val)
    >> =A0 =A0 index_check(idx)
    >> =A0 =A0 @data[idx] =3D val
    >> =A0 end
    >>
    >> https://gist.github.com/772827
    >>
    >> See also thread "Nooby question : multidimensional arrays.".
    >>
    >> I find the pattern matching _very_ elegant. =A0This also comes in handy
    >> in situations like this:

    >
    > Maybe I am not understanding it, but I thought that elegance is because
    > of splat operator (which I am sure I like).


    The splat operator is just part of the game as Josh has tried to
    demonstrate. The real power comes from pattern matching which will
    even work with multiple levels of nesting. And the mechanism is the
    same for method and block arguments which gives you one powerful
    mechanism usable in several places.

    > My gripe is about various
    > forms of parallel assignment and semantic/syntactic complexity because
    > of that. Or are you saying that once you say you need splat operator,
    > all this complexity is inevitable (of course, I can work around it by
    > not using it, but then how do you all use it?)


    No, I am saying that parallel assignment is just a special case of the
    assignment mechanism that is also in effect for method and block
    arguments. And while I don't use the fancy variants often (as Josh)
    when I use it it yields an elegant solution that would be more
    cumbersome without it.

    Kind regards

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Jan 12, 2011
    #8
  9. On Tue, Jan 11, 2011 at 3:30 PM, Robert Klemme
    <> wrote:
    > ... I find the pattern matching _very_ elegant. ... Generally I'd say
    > I don't use it overly often but when I use it it is really handy. ...


    On Tue, Jan 11, 2011 at 7:58 PM, Josh Cheek <> wrote:
    > I don't use it very often, but when I do, it usually makes an
    > elegant solution. I think part of the reason it doesn't seem that
    > way is because you are playing with it in too sterile of an environment.


    That last sentence seems an accurate assessment of why it perhaps
    doesn't seem much use to you, and what Josh Cheek and Robert Klemme
    say about those situations where they use it seems appropriate,
    although I haven't personally used it in those types of situations
    because my Ruby use is relatively simple.

    On Tue, Jan 11, 2011 at 8:29 PM, Kedar Mhaswade
    <> wrote:
    > ... This however is already covered by me as the first case (with HIGH
    > elegance rating) since you are expecting the line to contain exactly two
    > strings ... and hence the (expected) number of lvalues = number of rvalues.
    > I do like/understand such application of parallel assignment.


    Strangely, that's the situation (number of lvalues == number of
    rvalues) when I definitely dislike its use (unless it might be
    necessary to ensure all the rvalues are calculated before any
    assignment takes place - might side effects make this necessary?), for
    two (and a quarter) reasons.

    First, whenever I've benchmarked parallel assignment against
    individual assignment, I've found the parallel assignment somewhat
    slower. The swap is more elegant, but even that seems slower.

    Second, parallel assignment can make it difficult to see what is being
    assigned to what. In the following, is it instantly obvious what e is
    being set to?
    # a, b, c, d, e, f, g, h = q, r, s, t, u, v, w, x
    If it is instantly obvious, try more l and r values and/or try longer
    variable names and/or values and/or split the assignment expression
    over multiple lines!

    As an actual example, this from Date:
    def initialize(ajd=0, of=0, sg=ITALY)
    @ajd, @of, @sg = ajd, of, sg
    # ...
    end
    Admittedly it's easy here to see what's being assigned to what, but
    even so is that really better than the alternative just below? Is
    there a reason for using the parallel assignment in the actual
    example, other than aesthetics?
    def initialize(ajd=0, of=0, sg=ITALY)
    @ajd = ajd; @of = of; @sg = sg
    # ...
    end

    The quarter is the positive side of the negative point of the second,
    that explicit individual assignment is easier visually/cognitively
    than parallel assignment.


    *** benchmarks

    require "benchmark"
    a = b = c = d = e = f = g = h = nil; x = y = nil
    kt = 1_000_000
    Benchmark.bm( 22 ) do |bm|
    bm.report( "parallel assignment" ) { kt.times{
    a, b, c, d, e, f, g, h = 17, 23, 13, 48, 42, 46, 26, 24 } }
    bm.report( "individual assignment" ) { kt.times{
    a = 17; b = 23; c = 13; d = 48; e = 42; f = 46; g = 26; h = 24 } }
    bm.report( "swap elegant" ) { kt.times{
    x = 113; y = 355; x, y = y, x } }
    bm.report( "swap messy" ) { kt.times{
    x = 113; y = 355; z = x; x = y; y = z } }
    end

    Using Linux, Ruby 1.9.1, but I've had similar results on MS Windows.
    user system total real
    parallel assignment 0.630000 0.000000 0.630000 ( 0.635576)
    individual assignment 0.400000 0.000000 0.400000 ( 0.393652)
    swap elegant 0.500000 0.000000 0.500000 ( 0.506171)
    swap messy 0.300000 0.000000 0.300000 ( 0.298167)

    MS Windows: ruby 1.9.1p430 (2010-08-16 revision 28998) [i386-mingw32]
    user system total real
    parallel assignment 0.531000 0.000000 0.531000 ( 0.530000)
    individual assignment 0.327000 0.000000 0.327000 ( 0.335000)
    swap elegant 0.500000 0.000000 0.500000 ( 0.490000)
    swap messy 0.296000 0.000000 0.296000 ( 0.300000)

    MS Windows: jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7)
    (Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
    user system total real
    parallel assignment 0.735000 0.000000 0.735000 ( 0.705000)
    individual assignment 0.460000 0.000000 0.460000 ( 0.460000)
    swap elegant 0.560000 0.000000 0.560000 ( 0.560000)
    swap messy 0.425000 0.000000 0.425000 ( 0.425000)
    Colin Bartlett, Jan 12, 2011
    #9
  10. >> I do like/understand such application of parallel assignment.
    >
    > Strangely, that's the situation (number of lvalues == number of
    > rvalues) when I definitely dislike its use (unless it might be
    > necessary to ensure all the rvalues are calculated before any
    > assignment takes place - might side effects make this necessary?), for
    > two (and a quarter) reasons.


    Interesting (yeah, it's a matter of taste).
    But when number of variables is <=3, it looks very readable and easily
    understandable.

    > First, whenever I've benchmarked parallel assignment against
    > individual assignment, I've found the parallel assignment somewhat
    > slower. The swap is more elegant, but even that seems slower.


    That's a good point, but it's judgmental based on how frequently the
    code gets called.

    > # a, b, c, d, e, f, g, h = q, r, s, t, u, v, w, x
    > If it is instantly obvious, try more l and r values and/or try longer
    > variable names and/or values and/or split the assignment expression
    > over multiple lines!


    Well, one can always abuse a feature. I think number of variables should
    be <=3, e.g.
    a, b, c = q, r ,s
    @d, @e, @f = t(a), u(b), v(c) # ...

    >
    > As an actual example, this from Date:
    > def initialize(ajd=0, of=0, sg=ITALY)
    > @ajd, @of, @sg = ajd, of, sg
    > # ...
    > end
    > Admittedly it's easy here to see what's being assigned to what, but
    > even so is that really better than the alternative just below? Is
    > there a reason for using the parallel assignment in the actual
    > example, other than aesthetics?
    > def initialize(ajd=0, of=0, sg=ITALY)
    > @ajd = ajd; @of = of; @sg = sg
    > # ...
    > end
    >
    > The quarter is the positive side of the negative point of the second,
    > that explicit individual assignment is easier visually/cognitively
    > than parallel assignment.


    Yeah. And the (others') wisdom suggests that if and when you find a
    situation to apply it, it (usually) renders an elegant solution.

    -Kedar

    --
    Posted via http://www.ruby-forum.com/.
    Kedar Mhaswade, Jan 13, 2011
    #10
  11. On Wed, Jan 12, 2011 at 10:44 AM, Colin Bartlett
    <> wrote:
    > First, whenever I've benchmarked parallel assignment against
    > individual assignment, I've found the parallel assignment somewhat
    > slower. The swap is more elegant, but even that seems slower.


    Parallel assignment is generally slower than straight-up assignment in
    1.9 and JRuby because it stands up a full Ruby Array for the RHS and
    result of the entire assignment expression:

    ~/projects/jruby =E2=9E=94 jruby -e "p((a, b, c =3D 1, 2, 3))"
    [1, 2, 3]

    As you would expect this is a significant cost compared to just
    assigning the values directly. JRuby can improve this when it knows
    that the assignment is not being used as an expression:

    ~/projects/jruby =E2=9E=94 jruby -rbenchmark -e "2.times{ puts
    Benchmark.measure { 10000000.times {a,b,c=3D1,2,3} } }"
    1.924000 0.000000 1.924000 ( 1.812000)
    1.810000 0.000000 1.810000 ( 1.810000)

    ~/projects/jruby =E2=9E=94 jruby -rbenchmark -e "2.times{ puts
    Benchmark.measure { 10000000.times {a,b,c=3D1,2,3; nil} } }"
    1.073000 0.000000 1.073000 ( 0.959000)
    0.884000 0.000000 0.884000 ( 0.884000)

    There are also some implementations that "cheat" (I mean that in the
    nicest way possible) and don't bother producing that array return
    value at all, and they perform much better on parallel assignment as a
    result.

    - Charlie
    Charles Oliver Nutter, Jan 14, 2011
    #11
  12. On Fri, Jan 14, 2011 at 4:41 PM, Charles Oliver Nutter
    <> wrote:
    > Parallel assignment is generally slower than straight-up assignment in
    > 1.9 and JRuby because it stands up a full Ruby Array for the RHS and
    > result of the entire assignment expression:


    I'd assumed it was something like that. Thanks for the explanation.

    > As you would expect this is a significant cost compared to just
    > assigning the values directly. JRuby can improve this when it knows
    > that the assignment is not being used as an expression:
    > ...
    > There are also some implementations that "cheat" (I mean that in the
    > nicest way possible)


    I don't know if you've heard of the English magician Paul Daniels, but
    I'm very fond of a phrase he uses to contrast himself with some people
    who are, let us say, not self-admitted magicians. "I cheat, but I
    cheat honestly".

    > and don't bother producing that array return value at all,
    > and they perform much better on parallel assignment as a result.


    Cheating honestly, I think!

    That's interesting, and the "cheating" idea hadn't ocurred to me. From
    the benchmarks below (similar to those you quoted; I did actually run
    the benchmarks twice, but the runs were very similar, so to avoid
    clutter I've only given one run) it seems MRC 1.9.1 is also cheating
    honestly if it can.

    Now the only thing that's puzzling me is why the MRI 1.9.1 "cheating
    honestly" version of parallel assignment seems to be slightly but
    clearly faster than the MRI 1.9.1 single assignment!

    require "benchmark"
    kt = 10_000_000
    nn = 1
    nn.times{ puts Benchmark.measure { kt.times {a,b,c=1,2,3 } } }
    nn.times{ puts Benchmark.measure { kt.times {a,b,c=1,2,3; nil} } }
    nn.times{ puts Benchmark.measure { kt.times {a = 1; b = 2; c = 3 } } }

    jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7)
    (Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
    3.038000 0.000000 3.038000 ( 3.007000)
    1.561000 0.000000 1.561000 ( 1.562000)
    1.558000 0.000000 1.558000 ( 1.558000)

    ruby 1.9.1p430 (2010-08-16 revision 28998) [i386-mingw32]
    3.962000 0.000000 3.962000 ( 3.963000)
    1.747000 0.000000 1.747000 ( 1.741000)
    2.106000 0.000000 2.106000 ( 2.105000)
    Colin Bartlett, Jan 14, 2011
    #12
  13. On Fri, Jan 14, 2011 at 2:45 PM, Colin Bartlett <> w=
    rote:
    > Now the only thing that's puzzling me is why the MRI 1.9.1 "cheating
    > honestly" version of parallel assignment seems to be slightly but
    > clearly faster than the MRI 1.9.1 single assignment!


    Yes, that is a bit baffling! I have no explanation for that. As you
    can see in JRuby, the times for the non-expression parallel assignment
    and the normal assignment are roughly the same.

    > require "benchmark"
    > kt =3D 10_000_000
    > nn =3D 1
    > nn.times{ puts Benchmark.measure { kt.times {a,b,c=3D1,2,3 =C2=A0 =C2=A0 =

    } } }
    > nn.times{ puts Benchmark.measure { kt.times {a,b,c=3D1,2,3; nil} } }
    > nn.times{ puts Benchmark.measure { kt.times {a =3D 1; b =3D 2; c =3D 3 } =

    } }
    >
    > jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7)
    > =C2=A0(Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
    > =C2=A03.038000 =C2=A0 0.000000 =C2=A0 3.038000 ( =C2=A03.007000)
    > =C2=A01.561000 =C2=A0 0.000000 =C2=A0 1.561000 ( =C2=A01.562000)
    > =C2=A01.558000 =C2=A0 0.000000 =C2=A0 1.558000 ( =C2=A01.558000)


    FWIW, you'd get better results here if you ran a couple iterations,
    and of course if you specified --server it's significantly better...

    ~/projects/jruby =E2=9E=94 jruby -v passign.rb
    jruby 1.6.0.RC1 (ruby 1.8.7 patchlevel 330) (2011-01-14 da2bb9d) (Java
    HotSpot(TM) Client VM 1.6.0_22) [darwin-i386-java]
    1.952000 0.000000 1.952000 ( 1.839000)
    1.784000 0.000000 1.784000 ( 1.784000)
    1.796000 0.000000 1.796000 ( 1.796000)
    0.919000 0.000000 0.919000 ( 0.919000)
    0.865000 0.000000 0.865000 ( 0.865000)
    0.856000 0.000000 0.856000 ( 0.856000)
    0.961000 0.000000 0.961000 ( 0.961000)
    0.924000 0.000000 0.924000 ( 0.924000)
    0.880000 0.000000 0.880000 ( 0.880000)

    ~/projects/jruby =E2=9E=94 jruby --server -v passign.rb
    jruby 1.6.0.RC1 (ruby 1.8.7 patchlevel 330) (2011-01-14 da2bb9d) (Java
    HotSpot(TM) Server VM 1.6.0_22) [darwin-i386-java]
    1.388000 0.000000 1.388000 ( 1.324000)
    1.086000 0.000000 1.086000 ( 1.086000)
    1.034000 0.000000 1.034000 ( 1.034000)
    0.522000 0.000000 0.522000 ( 0.522000)
    0.500000 0.000000 0.500000 ( 0.500000)
    0.491000 0.000000 0.491000 ( 0.491000)
    0.517000 0.000000 0.517000 ( 0.517000)
    0.485000 0.000000 0.485000 ( 0.485000)
    0.496000 0.000000 0.496000 ( 0.496000)
    Charles Oliver Nutter, Jan 15, 2011
    #13
  14. Josh Cheek wrote in post #974019:
    > On Tue, Jan 11, 2011 at 8:29 AM, Kedar Mhaswade
    > <>wrote:
    >
    >>
    >> Kedar
    >>
    >> --
    >> Posted via http://www.ruby-forum.com/.
    >>
    >>

    > I don't use it very often, but when I do, it usually makes an elegant
    > solution. I think part of the reason it doesn't seem that way is because
    > you
    > are playing with it in too sterile of an environment. For example, you
    > rate
    > "x, (y, (z, a))=[1, [2, [3, 4]]]" as lowest, suggesting it is equivalent
    > to
    > "x=1;y=2;z=3;a=4" but this is not true. If you are actually assigning
    > with
    > literals, you would, of course, use the equivalent way, but if your data
    > comes in as nested arrays, then you can't assign like that, instead you
    > have
    > to do something like this:
    >
    > def parallel(values)
    > x, (y, (z, a))=values
    > [x,y,z,a]
    > end


    Instead you could also do:

    x, y, z, a = values.flatten

    Which avoids making you look like your writing in LISP.

    For small stuff parrallel assignment makes it look elegant, but like any
    language feature it can be abused. Although I don't think I've ever
    actually found a case where I've wanted to use this. Especially when
    most of the time my 'x, y, z and a' variables are unrelated so I don't
    want to use them together in the same statement.

    --
    Posted via http://www.ruby-forum.com/.
    Joseph Lenton, Jan 15, 2011
    #14
  15. [Note: parts of this message were removed to make it a legal post.]

    >
    > > def parallel(values)
    > > x, (y, (z, a))=values
    > > [x,y,z,a]
    > > end

    >
    > Instead you could also do:
    >
    > x, y, z, a = values.flatten
    >
    > Which avoids making you look like your writing in LISP.



    These two bits of code are not the same thing.

    a, (b, c) = [1, [2, [3, 4]]]

    a #=> 1
    b #=> 2
    c #=> [3, 4]

    a, b, c = [1, [2, [3, 4]]].flatten

    a #=> 1
    b #=> 2
    c #=> 3


    On Sat, Jan 15, 2011 at 11:04 AM, Joseph Lenton <> wrote:

    > Josh Cheek wrote in post #974019:
    > > On Tue, Jan 11, 2011 at 8:29 AM, Kedar Mhaswade
    > > <>wrote:
    > >
    > >>
    > >> Kedar
    > >>
    > >> --
    > >> Posted via http://www.ruby-forum.com/.
    > >>
    > >>

    > > I don't use it very often, but when I do, it usually makes an elegant
    > > solution. I think part of the reason it doesn't seem that way is because
    > > you
    > > are playing with it in too sterile of an environment. For example, you
    > > rate
    > > "x, (y, (z, a))=[1, [2, [3, 4]]]" as lowest, suggesting it is equivalent
    > > to
    > > "x=1;y=2;z=3;a=4" but this is not true. If you are actually assigning
    > > with
    > > literals, you would, of course, use the equivalent way, but if your data
    > > comes in as nested arrays, then you can't assign like that, instead you
    > > have
    > > to do something like this:
    > >
    > > def parallel(values)
    > > x, (y, (z, a))=values
    > > [x,y,z,a]
    > > end

    >
    > Instead you could also do:
    >
    > x, y, z, a = values.flatten
    >
    > Which avoids making you look like your writing in LISP.
    >
    > For small stuff parrallel assignment makes it look elegant, but like any
    > language feature it can be abused. Although I don't think I've ever
    > actually found a case where I've wanted to use this. Especially when
    > most of the time my 'x, y, z and a' variables are unrelated so I don't
    > want to use them together in the same statement.
    >
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
    Adam Prescott, Jan 17, 2011
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. wired
    Replies:
    35
    Views:
    1,695
    llewelly
    Jul 7, 2003
  2. Replies:
    0
    Views:
    87
  3. Gavin
    Replies:
    5
    Views:
    126
    Jesús Gabriel y Galán
    Feb 16, 2010
  4. Elegance is an attitude

    , Oct 19, 2008, in forum: Javascript
    Replies:
    0
    Views:
    96
  5. John Ladasky
    Replies:
    10
    Views:
    218
    Peter Cacioppi
    Oct 8, 2013
Loading...

Share This Page