[#407882] Ruby extremely slow compared to PHP — Mick Jagger <lists@...>

Hello there, how are you? Hope you are fine. I am a PHP programmer

17 messages 2013/06/02

[#407908] TCPServer/Socket and Marshal problem — Panagiotis Atmatzidis <atma@...>

Hello,

18 messages 2013/06/03

[#407946] Is rubyquiz.com dead? — Alphonse 23 <lists@...>

Thread title says everything.

18 messages 2013/06/04

[#408012] Need help understanding recursion. — pedro oliva <lists@...>

Ive been reading Chris Pine's book 'Learn to Program' and its been going

11 messages 2013/06/06

[#408129] Getting Started With Development — Chamila Wijayarathna <cdwijayarathna@...>

I'm new to Ruby Development. I downloaded source from Github, but couldn't

24 messages 2013/06/11
[#408131] Re: Getting Started With Development — Per-erik Martin <lists@...> 2013/06/11

Ruby is often installed on linux, or can be easily installed with the

[#408146] Re: Getting Started With Development — "Chamila W." <lists@...> 2013/06/11

Per-erik Martin wrote in post #1112021:

[#408149] Re: Getting Started With Development — "Carlo E. Prelz" <fluido@...> 2013/06/11

Subject: Re: Getting Started With Development

[#408198] NokoGiri XML Parser — "Devender P." <lists@...>

Hi,

11 messages 2013/06/13

[#408201] trying to load a .rb file in irb — "Eric D." <lists@...>

I am trying to load a ruby program into irb and it will not load.

12 messages 2013/06/13

[#408205] Can I use Sinatra to render dynamic pages? — Ruby Student <ruby.student@...>

Hell Team,

18 messages 2013/06/13
[#408219] Re: Can I use Sinatra to render dynamic pages? — Nicholas Van Weerdenburg <vanweerd@...> 2013/06/14

You should be able to do this without JavaScript by using streaming.

[#408228] Re: Can I use Sinatra to render dynamic pages? — Ruby Student <ruby.student@...> 2013/06/14

Well, I got some good suggestions from everyone here. I thank you all for

[#408275] Compare and sort one array according to another. — masta Blasta <lists@...>

I have two arrays of objects that look something like this:

14 messages 2013/06/17

[#408276] Comparing objects — "Thom T." <lists@...>

How do I compare two objects in Ruby, considering only attributes

15 messages 2013/06/17

[#408307] getting the most out of Ruby — robin wood <lists@...>

I write a lot of scripts in Ruby, most are small simple things but some

13 messages 2013/06/18

[#408309] Creating ruby script exe — Rochit Sen <lists@...>

Hi All,

17 messages 2013/06/18

[#408357] Beginners problem with database and datamapper — cristian cristian <lists@...>

Hi all!

28 messages 2013/06/20

[#408437] How do I input a variable floating point number into Ruby Programs — "Michael P F." <lists@...>

I want to evaluate the following interactively:

10 messages 2013/06/23

[#408518] #!/usr/bin/env: No such file or directory — Todd Sterben <lists@...>

I am new to both linux and ruby. I am using Ubuntu and Ruby 1.9

17 messages 2013/06/27

[#408528] Designing a Cabinet class — Mike Vezzani <lists@...>

Hello all,

12 messages 2013/06/27

[#408561] Find elment in array of hashes — Rodrigo Lueneberg <lists@...>

array = {:id=>1, :price =>0.25} # index[0]

23 messages 2013/06/28

Re: Need help understanding recursion.

From: Alphonse 23 <lists@...>
Date: 2013-06-06 07:17:36 UTC
List: ruby-talk #408019
Recursive algorithms are essentially self-calling algorithms -- so any
method that calls itself is recursive. Typically you'll see the
self-calling section in the return statement. In ruby that would be the
last line of the method before the final end statement. Also, all
recursive methods have a base case, the condition that tells the method
when to exit.

The benefits are sometimes performance gains, lower space complexity,
and more elegant written code (though that's up for you to decide).
Mathematicians more often consider recursive methods more elegant, where
typically the non-math oriented prefer iterative methods for some
reason. Though one way isn't necessarily better than the other.

I think what would help you is to see examples of recursive methods
compared directly to their iterative counterparts, and compare their
running speeds. The fibonacci algorithm is one of the most popular
examples used. Read more about the specific sequence here:
http://en.wikipedia.org/wiki/Fibonacci_number

Below are two versions that calculate the nth number in the fibonacci
sequence:

# iterative
def fibIter(n)
  return 0 if n == 0
  fibPrev, fib = 1, 1
  (n.abs - 2).times { fibPrev, fib = fib, fib + fibPrev }
  fib * (n<0 ? (-1)**(n+1) : 1)
end

# recursive
def fibRec(n)
  if n <= -2
    (-1)**(n+1) * fibRec(n.abs)
  elsif n <= 1
    n.abs
  else
    fibRec(n-1) + fibRec(n-2)
  end
end

If you benchmark these, you'll notice the iterative method typically
performs better than the recursive one.

require 'benchmark'

Benchmark.bm do |x|
  x.report("fibIter 10") { fibIter(10) }
  x.report("fibRec 10") { fibRec(10) }
  x.report("fibIter 30") { fibIter(30) }
  x.report("fibRec 30") { fibRec(30) }
end
       user     system      total        real
fibIter  0.000000   0.000000   0.000000 (  0.000014)
fibRec  0.000000   0.000000   0.000000 (  0.000032)
fibIter  0.000000   0.000000   0.000000 (  0.000013)
fibRec  0.340000   0.000000   0.340000 (  0.350754)

So in this case, the iterative method is faster than the recursive
counter part.

Let me show you an example where a recursive method is much faster. 
Below are two sorting algorithms, bubble sort and quick sort. Bubble 
sort is a iterative sorting algorithm and quick sort is a recursive 
sorting algorithm.

class Array
  def bubblesort
    length.times do |j|
      for i in 1...(length - j)
        if self[i] < self[i - 1]
          self[i], self[i - 1] = self[i - 1], self[i]
        end
      end
    end
    self
  end

  def quick_sort
    return self if length <= 1
    pivot = self[length / 2]
    find_all { |i| i <  pivot }.quick_sort +
      find_all { |i| i == pivot } +
      find_all { |i| i >  pivot }.quick_sort
  end
end

ary =
[0,1,4,5,6,7,8,9,12,26,45,67,78,90,98,123,211,234,456,769,865,2345,3215,14345,24324]
ary.shuffle!

Benchmark.bm do |x|
  x.report("bubble sort") { ary.bubblesort }
  ary.shuffle!
  x.report("quick sort") { ary.quick_sort }
end

       user     system      total        real
bubble sort  0.000000   0.000000   0.000000 (  0.000165)
quick sort  0.000000   0.000000   0.000000 (  0.000096)

As you can see in the benchmarking test, quicksort typically works in
half the time of bubble sort. At worst, quicksort will always sort at
nlog(n) times, where n is the number of array elements (In CS
terminology this is called big O nlog(n) time). A exhaustive iterative
method, such as bubble sort, has a worst case of n^2 time.

Here's an animation written in javascript that illustrates the
differences very well visually:
http://liamks.github.io/Sorting-Visualization/

An important example of a recursive algorithm improving performance is
the binary search algorithm. This algorithm greatly improve searching
speeds in sorted arrays. A linear search will always work in 0(n) time,
whereas a binary search at worst works in O(log(n)) time.

class Array
  def binary_search(val, low=0, high=(length - 1))
    return nil if high < low
    mid = (low + high) / 2
    case
      when self[mid] > val then binary_search(val, low, mid-1)
      when self[mid] < val then binary_search(val, mid+1, high)
      else mid
    end
  end
end

As you can see from the examples above, recursive methods sometimes
improve performance speeds (binary search & sorting) and sometimes don't
(fibonacci). One isn't necessarily better than the other, but they do
offer stylistic differences, which would be important to a rubyist.
Performance gains are not typically important in scripting languages,
but it becomes important in lower level languages like C, C++, Java, and
Go. Where ever running times become important, you should really
understand recursion.

Recursion is even more important in purely functionally programming
languages like Scheme, Lisp, and Haskell. Ruby, as an applied functional
and scripting programming language, has too many performance issues to
make all recursive techniques practical.

Some languages are capable of performing tail recursion, which is a type
of recursive technique that involves using an accumulator variable to
reduce building up a large recursive stack. Tail recursive methods often
have huge performance gains, but not all environments support it
currently:
(http://stackoverflow.com/questions/3616483/why-does-the-jvm-still-not-support-tail-call-optimization)
Though, it's been such a major issue for a long time, I'm certain it'll
become available in the future.

Id say, take it easy. Maybe Chris Pine is using a bad starter example. I
struggled with recursion when I had to first learn it, most do, but it 
is a
really nice alternative way of writing eloquent
code -- and after you've master it you'll feel a very strong
appreciation for recursive solutions and those that understand it. It
will also help you understand more advanced CS topics in the future.
Functional/recursive programming techniques are leading the way in both
industry and academia -- so it would be of a huge advantage to
understand it.

Sorry for the long post. I hope this helped.

-- 
Posted via http://www.ruby-forum.com/.

In This Thread