TER - Haskell
module Fib where
fib2 :: Int -> Integer
fib2 n = fib2p n (0, 1) where
fib2p 0 (a, _) = a
fib2p n (a, b) = fib2p (n - 1) (b, a + b)
TER - Scala
object Fib {
import scala.math.BigInt
def fib2(n: Int): BigInt = {
def fib2p(n: Int, acc: (BigInt, BigInt)): BigInt = n match {
case 0 => acc._1
case _ => fib2p(n - 1, (acc._2, acc._1 + acc._2))
}
fib2p(n, (0, 1))
}
}
TER - Elixir
defmodule Fib do
@moduledoc false
def fib2(n), do: fib2p(n, {0, 1})
defp fib2p(0, {a, _}), do: a
defp fib2p(n, {a, b}), do: fib2p(n - 1, {b, a + b})
end
TER - Summary
|
Haskell |
Scala |
Elixir |
Performance |
0.012 |
0.115 |
0.008 |
Observations |
Lazy :) |
Slowest :) |
No BigInt :) |
- fib2(10000)
- Much faster (in general)
- Stack does not explode :)
Lazy - Haskell
module Fib where
fib3 :: Int -> Integer
fib3 n = fibs !! n where
fibs = 0 : 1 : next fibs where
next (a : t@(b:_)) = (a + b) : next t
Lazy - Scala
object Fib {
import scala.math.BigInt
def fib3(n: Int): BigInt = {
def fibs(a: BigInt, b: BigInt): Stream[BigInt] = a #:: fibs(b, a + b)
fibs(BigInt(0), BigInt(1))(n)
}
}
Lazy - Elixir
defmodule Fib do
@moduledoc false
def fib3(n), do: fibs() |> Enum.at(n)
defp fibs(), do: Stream.unfold({0, 1}, fn {a, b} -> {a, {b, a + b}} end)
end
Lazy - Summary
|
Haskell |
Scala |
Elixir |
Performance |
0.008 |
0.081 |
0.012 |
Observations |
Using timeItT |
Roll your own |
Using :time.tc/1 |
- fib3(10000)
- About as fast as TER
- Elegant :)