patternrubyMinor
Ruby Fibonacci(n) recursive computation optimized with reflection
Viewed 0 times
reflectioncomputationfibonacciwithoptimizedrecursiveruby
Problem
The idea is to take the common-known (and awfully bad performing) Fibonacci(n) recursive method:
and to optimize it with some Ruby reflection:
Since the execution time for
# recursively computate fibonacci(n)
def fib(n)
n <= 2 ? 1 : fib(n-2) + fib(n-1)
endand to optimize it with some Ruby reflection:
require 'benchmark'
def fib(n)
# if n<= 2 fib(n) = 1
return 1 if n <= 2
# if @fib_n is defined it means that another instance of this method
# has already computed it, so I just return its value
return instance_variable_get("@fib_#{n}") if instance_variable_get("@fib_#{n}")
# else I have to set fib_n and return its value
instance_variable_set("@fib_#{n}", ( fib(n-2) + fib(n-1) ) )
end
Benchmark.bm(30) do |x|
x.report("fibonacci(#{ARGV[0]}) computation time:") {$fib = fib(ARGV[0].to_i)}
end
puts "fib(#{ARGV[0]}) = #{$fib}"Since the execution time for
fib(36) drops from about 4 sec to 0.000234 sec, I guess it's working! But since I'm a Ruby novice (and since this is my first attempt with reflection), I'd still like to have my code peer-reviewed. - Is my choice to use '@fib_n' instance variables correct or there is a better choice?
- Does anyone know a better Ruby optimization for the recursive computation of Fibonacci members? (I know, the most efficient computation for Fibonacci is the iterative one, but here I'm strictly interested in the recursive one).
Solution
considering that this is Code Review, I have to say that you probably don't want to use an instance variable. You expose the internal data, and any user could destroy the workings of your method inadvertently. In Ruby 1.9, Ruby added a very interesting feature for just these types of situations that involve infinite sequences. It's called a
It's true that
Another option for this is to put the data in a module:
And use it like so:
Fiber.It's true that
Fibers aren't perfect for situations where you have to go backwards in the sequence in addition to forward. Another option for this is to put the data in a module:
module Fibonacci
@fib=[0,1,1]
def self.fib_array(n)
@fib[n] ||= fib_array(n-2) + fib_array(n-1)
end
endAnd use it like so:
Fibonacci.fib_array(42)Code Snippets
module Fibonacci
@fib=[0,1,1]
def self.fib_array(n)
@fib[n] ||= fib_array(n-2) + fib_array(n-1)
end
endFibonacci.fib_array(42)Context
StackExchange Code Review Q#12194, answer score: 2
Revisions (0)
No revisions yet.