I encountered problem with Array#flatten slowness (it can be much
faster if no argument is given) while solving current QUIZ (see
ruby-talk mail list).

Sorry if the issue is already solved in HEAD revision. I have not checked it.
I just searched though bugs and did not find anything related to
'flatten' slowness.

My ruby version is
 ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

The code to reveal the problem:

 #!/usr/bin/ruby

 N = 10000

 inputs = []
 inputs << '0 ' + (1..N-1).to_a.join(' - ') + ' -'
 inputs << (1..N).to_a.join(' ') + (" +" * (N-1))

 class Array
  def flatten2
    res = []
    x = self.reverse
    while !x.empty?
      a = x.pop
      if a.is_a?(Array)
        x.push(*a)
      else
        res << a
      end
    end
    res.reverse
  end
 end

 require 'benchmark'

 inputs.each do |input|
  stack = []
  input.strip.split.each do |token|
    # puts "TOKEN '#{token.inspect}'"
    case token
    when '*', '+', '/', '-'
      stack << [stack.pop, token, stack.pop].reverse!
    else
      stack << token
    end
  end

#####################

>ruby test_flatten.rb
      user     system      total        real
original flatten  5.125000   0.000000   5.125000 (  5.141000)
self-made flatten  0.032000   0.000000   0.032000 (  0.031000)
true
      user     system      total        real
original flatten  5.063000   0.000000   5.063000 (  5.079000)
self-made flatten  0.031000   0.000000   0.031000 (  0.031000)
true

######################
For N = 20000 we will get

>ruby test_flatten.rb
      user     system      total        real
original flatten 20.453000   0.000000  20.453000 ( 20.500000)
self-made flatten  0.062000   0.000000   0.062000 (  0.063000)
true
      user     system      total        real
original flatten 20.187000   0.000000  20.187000 ( 20.219000)
self-made flatten  0.063000   0.000000   0.063000 (  0.062000)
true

So, 'flatten' time  grows  quadratically while 'flatten2' time -- linearly.


See my message in QUIZ thread  http://www.ruby-forum.com/topic/133483#595902

Best regards,
Artem