Q:

Generating a random alphanumeric string succinctly and efficiently

I want to generate a random alphanumeric string in ruby, as succinctly and efficiently as possible. The following solution works, but is obviously not very efficient. 
Please review the following code, bearing in mind that I am trying to keep it as succinct and readable as possible while improving efficiency. Be sure to include a detailed explanation in your answer.
([nil]*8).map { ((48..57).to_a+(65..90).to_a+(97..122).to_a).sample.chr }.join

A:

You could use
Array.new(8){[*'0'..'9', *'a'..'z', *'A'..'Z'].sample}.join

From the documentation for Array:

new(size=0, obj=nil) new(array) new(size) {|index| block }
Returns a new array. In the first form, the new array is empty. In the second it is created with size copies of obj (that is, size references to the same obj). The third form creates a copy of the array passed as a parameter (the array is generated by calling to_ary on the parameter). In the last form, an array of the given size is created. Each element in this array is calculated by passing the element’s index to the given block and storing the return value.

Perhaps it is better to create the array with the valid characters once in advance:
range = [*'0'..'9', *'a'..'z', *'A'..'Z']
Array.new(8){range.sample}.join

I made a Benchmark for the solutions.
require 'benchmark'
N = 10_000 #Number of Test loops

Benchmark.bmbm(10) {|b|
  
  b.report('Nat'      ) { N.times { ([nil]*8).map { ((48..57).to_a+(65..90).to_a+(97..122).to_a).sample.chr }.join } }
  b.report('tokland') { N.times { 8.times.map { [*'0'..'9', *'a'..'z', *'A'..'Z'].sample }.join } }
  b.report('knut'   ) { N.times { Array.new(8){[*'0'..'9', *'a'..'z', *'A'..'Z'].sample}.join } }
  b.report('Natinit') { 
    range = ((48..57).to_a+(65..90).to_a+(97..122).to_a)
    N.times { ([nil]*8).map { range.sample.chr }.join }
  }
  b.report('knutinit') { 
      range = ((48..57).to_a+(65..90).to_a+(97..122).to_a)
      N.times { Array.new(8){range.sample}.join }
  }

} #Benchmark

The result:
Rehearsal ---------------------------------------------
Nat         0.765000   0.000000   0.765000 (  0.765625)
tokland     2.172000   0.000000   2.172000 (  2.171875)
knut        1.953000   0.000000   1.953000 (  1.984375)
Natinit     0.063000   0.000000   0.063000 (  0.062500)
knutinit    0.078000   0.000000   0.078000 (  0.078125)
------------------------------------ total: 5.031000sec

                user     system      total        real
Nat         0.781000   0.000000   0.781000 (  0.781250)
tokland     1.953000   0.000000   1.953000 (  1.968750)
knut        1.922000   0.000000   1.922000 (  1.921875)
Natinit     0.063000   0.000000   0.063000 (  0.062500)
knutinit    0.078000   0.000000   0.078000 (  0.078125)

@Nat: Gratulation, your version is the fastest ;)
To analyze the fastest way to build the range I used the following benchmark:
Benchmark.bmbm(10) {|b|
  
  b.report('Natinit') { 
    N.times { ((48..57).to_a+(65..90).to_a+(97..122).to_a) }
  }
  b.report('knutinit') { 
      N.times { [*'0'..'9', *'a'..'z', *'A'..'Z'] }
  }
} #Benchmark

Result:
Rehearsal ---------------------------------------------
Natinit     0.093000   0.000000   0.093000 (  0.093750)
knutinit    0.250000   0.000000   0.250000 (  0.250000)
------------------------------------ total: 0.343000sec

    user     system      total        real
Natinit     0.094000   0.000000   0.094000 (  0.093750)
knutinit    0.219000   0.000000   0.219000 (  0.218750)

A:

I think this is both declarative and concise:
8.times.map { [*'0'..'9', *'a'..'z', *'A'..'Z'].sample }.join

It works because:

You can call map on times since >= 1.8.7 made it return an enumerator when called without block (a lot of methods do this now: each, each_cons, each_slice, ...). 
You can build a range with objects of any class as long as they support <=> and succ. 
You can explode any enumerable. If you don't like the exploding syntax, use ['0'..'9', 'a'..'z', 'A'..'Z'].flat_map(&:to_a).

The only problem with this being a one-liner (as requested), it's that the array is re-created on every iteration. It would be better to assign it once to a variable outside the block:
cs = [*'0'..'9', *'a'..'z', *'A'..'Z']
8.times.map { cs.sample }.join

Alternatevely, you can write:
cs = [*'0'..'9', *'a'..'z', *'A'..'Z']
Array.new(8) { cs.sample }.join

A:

I've reviewed many means of random string generation of many, but this form is always the one I come back to:
rand(36**7...36**8).to_s(36)

It's a bit rougher to the more pleasing alternative rand(36**8).to_s(36), but it's also more accurate.
I also don't really care for Ruby's benchmarking class (read: I haven't bothered to learn how to utilize it), so I instead just timed how long using your original method takes to generate 100000 iterations versus the code above:
time echo "100000.times {puts ([nil]*8).map { ((48..57).to_a+(65..90).to_a+(97..122).to_a).sample.chr }.join}" | ruby
# ruby  8.37s user 0.55s system 99% cpu 8.926 total

time echo "100000.times {puts rand(36**7..(36**8)-1).to_s(36)}" | ruby
# ruby  0.59s user 0.34s system 97% cpu 0.949 total

In other words, while your original method occurs at a rate of 11,203 iterations per second. The code above occurs at a rate of 105,400 iterations per second. I'm sure this will vary from computer to computer, OS to OS, but anyone is certainly free to try this themselves.

