Skip to content

Instantly share code, notes, and snippets.

@pragdave
Created April 26, 2013 02:30
Show Gist options
  • Save pragdave/5464739 to your computer and use it in GitHub Desktop.
Save pragdave/5464739 to your computer and use it in GitHub Desktop.
defmodule FibSolver do
def fib(scheduler) do
scheduler <- { :ready, self }
receive do
{ :fib, n, client } ->
client <- { :answer, n, fib_calc(n), self }
fib(scheduler)
{:shutdown} ->
exit(0)
end
end
# very inefficient, deliberately
defp fib_calc(0), do: 1
defp fib_calc(1), do: 1
defp fib_calc(n), do: fib_calc(n-1) + fib_calc(n-2)
end
defmodule Scheduler do
def run(num_processes, module, func, to_calculate) do
processes = Enum.map(1..num_processes, fn(_) -> spawn(module, func, [self]) end)
schedule_processes(to_calculate, [], processes)
end
defp schedule_processes(queue, results, processes) do
receive do
{:ready, pid} when length(queue) > 0 ->
[ next | tail ] = queue
pid <- {:fib, next, self}
schedule_processes(tail, results, processes)
{:ready, pid} ->
pid <- {:shutdown}
if length(processes) > 1 do
schedule_processes(queue, results, List.delete(processes, pid))
else
Enum.sort(results, fn {n1,_}, {n2,_} -> n1 < n2 end)
end
{:answer, number, factorial, _pid} ->
schedule_processes(queue, [ {number, factorial} | results ], processes)
end
end
end
to_process = [27, 33, 35, 11, 36, 29, 18, 37, 21, 31, 19, 10, 14, 30,
15, 17, 23, 28, 25, 34, 22, 20, 13, 16, 32, 12, 26, 24]
Enum.each 1..10, fn num_processes ->
{time, result} = :timer.tc(Scheduler, :run, [num_processes, FibSolver, :fib, to_process])
if num_processes == 1 do
IO.puts inspect result
IO.puts "\n # time (s)"
end
:io.format "~2B ~.2f~n", [num_processes, time/1000000.0]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment