From: Colin Bartlett Date: 2011-01-13T01:44:10+09:00 Subject: Re: Parallel Assignments and Elegance/Complexity Ratio. 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)