Skip to content

Instantly share code, notes, and snippets.

@DominicFinn
Created May 18, 2013 20:58
Show Gist options
  • Save DominicFinn/5605772 to your computer and use it in GitHub Desktop.
Save DominicFinn/5605772 to your computer and use it in GitHub Desktop.
Testing performance of different ways to recursively calculate the Fibonacci sequence. Not a great test because a) it doesn't calculate high numbers in the sequence and it doesn't bench mark against iterative ways. Interesting nevertheless.
namespace CSharpEquiv
{
public static class Recursion
{
public static int Fib1(int x)
{
return (x == 1 || x == 2) ? 1 : Fib1(x - 1) + Fib1(x - 2);
}
public static int Fib2(int x)
{
if (x == 1 || x == 2)
return 1;
return Fib1(x - 1) + Fib1(x - 2);
}
public static int Fib3(int x)
{
switch (x)
{
case 1:
case 2:
return 1;
default:
return Fib1(x - 1) + Fib1(x - 2);
}
}
}
}
module Recursion
let rec fib1 x =
match x with
| 1 -> 1
| 2 -> 1
| x -> fib1 (x - 1) + fib1 (x - 2)
let rec fib2 x =
if(x = 1 || x = 2) then
1
else
fib2 (x - 1) + fib2 (x - 2)
Public Module Recursion
Public Function Fib1(x As Integer) As Integer
Return If(x = 1 Or x = 2, 1, Fib1(x - 1) + Fib1(x - 2))
End Function
Public Function Fib2(x As Integer) As Integer
If (x = 1 Or x = 2) Then
Return 1
End If
Return Fib2(x - 1) + Fib2(x - 2)
End Function
Public Function Fib3(x As Integer) As Integer
Select Case x
Case 1
Case 2
Return 1
Case Else
Return Fib2(x - 1) + Fib2(x - 2)
End Select
'Shouldn't be needed as the case else should be enough...
Return Fib2(x - 1) + Fib2(x - 2)
End Function
End Module
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
// Note to self, this is the start of the fibonacci sequence
//F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20
//0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
namespace FSharpConsoleApplicationTests
{
[TestClass]
public class RecursionTests
{
private readonly IList<Tuple<string, TimeSpan>> results;
public RecursionTests()
{
this.results = new List<Tuple<string, TimeSpan>>();
}
[TestMethod]
public void GiveAllTheTestsAGoodBashing()
{
for (var x = 1; x < 100000; x++)
{
FibonacciF1();
FibonacciF2();
FibonacciC1();
FibonacciC2();
FibonacciC3();
FibonacciV1();
FibonacciV2();
FibonacciV3();
}
RecordTheResultsToACsv();
}
private void RecordTheResultsToACsv()
{
var stringBuilder = new StringBuilder();
var groupedResults = this.results.GroupBy(item => item.Item1);
stringBuilder.Append(Environment.NewLine);
foreach (var groupedResult in groupedResults)
{
stringBuilder.Append(groupedResult.Key + "," + groupedResult.Average(x => x.Item2.TotalMilliseconds) + Environment.NewLine);
}
var s = new StreamWriter(@"C:\testResults\results.csv", true);
s.Write(stringBuilder.ToString());
s.Close();
}
[TestMethod]
public void FibonacciF1()
{
RunTest("F1", () =>
{
Assert.AreEqual(2, Recursion.fib1(3));
Assert.AreEqual(21, Recursion.fib1(8));
Assert.AreEqual(55, Recursion.fib1(10));
Assert.AreEqual(610, Recursion.fib1(15));
Assert.AreEqual(6765, Recursion.fib1(20));
});
}
[TestMethod]
public void FibonacciF2()
{
RunTest("F2", () =>
{
Assert.AreEqual(2, Recursion.fib2(3));
Assert.AreEqual(21, Recursion.fib2(8));
Assert.AreEqual(55, Recursion.fib2(10));
Assert.AreEqual(610, Recursion.fib2(15));
Assert.AreEqual(6765, Recursion.fib2(20));
});
}
[TestMethod]
public void FibonacciC1()
{
RunTest("C1", () =>
{
Assert.AreEqual(2, CSharpEquiv.Recursion.Fib1(3));
Assert.AreEqual(21, CSharpEquiv.Recursion.Fib1(8));
Assert.AreEqual(55, CSharpEquiv.Recursion.Fib1(10));
Assert.AreEqual(610, CSharpEquiv.Recursion.Fib1(15));
Assert.AreEqual(6765, CSharpEquiv.Recursion.Fib1(20));
});
}
[TestMethod]
public void FibonacciC2()
{
RunTest("C2", () =>
{
Assert.AreEqual(2, CSharpEquiv.Recursion.Fib2(3));
Assert.AreEqual(21, CSharpEquiv.Recursion.Fib2(8));
Assert.AreEqual(55, CSharpEquiv.Recursion.Fib2(10));
Assert.AreEqual(610, CSharpEquiv.Recursion.Fib2(15));
Assert.AreEqual(6765, CSharpEquiv.Recursion.Fib2(20));
});
}
[TestMethod]
public void FibonacciC3()
{
RunTest("C3", () =>
{
Assert.AreEqual(2, CSharpEquiv.Recursion.Fib3(3));
Assert.AreEqual(21, CSharpEquiv.Recursion.Fib3(8));
Assert.AreEqual(55, CSharpEquiv.Recursion.Fib3(10));
Assert.AreEqual(610, CSharpEquiv.Recursion.Fib3(15));
Assert.AreEqual(6765, CSharpEquiv.Recursion.Fib3(20));
});
}
[TestMethod]
public void FibonacciV1()
{
RunTest("VB1", () =>
{
Assert.AreEqual(2, VbEquiv.Recursion.Fib1(3));
Assert.AreEqual(21, VbEquiv.Recursion.Fib1(8));
Assert.AreEqual(55, VbEquiv.Recursion.Fib1(10));
Assert.AreEqual(610, VbEquiv.Recursion.Fib1(15));
Assert.AreEqual(6765, VbEquiv.Recursion.Fib1(20));
});
}
[TestMethod]
public void FibonacciV2()
{
RunTest("VB2", () =>
{
Assert.AreEqual(2, VbEquiv.Recursion.Fib2(3));
Assert.AreEqual(21, VbEquiv.Recursion.Fib2(8));
Assert.AreEqual(55, VbEquiv.Recursion.Fib2(10));
Assert.AreEqual(610, VbEquiv.Recursion.Fib2(15));
Assert.AreEqual(6765, VbEquiv.Recursion.Fib2(20));
});
}
[TestMethod]
public void FibonacciV3()
{
RunTest("VB3", () =>
{
Assert.AreEqual(2, VbEquiv.Recursion.Fib2(3));
Assert.AreEqual(21, VbEquiv.Recursion.Fib2(8));
Assert.AreEqual(55, VbEquiv.Recursion.Fib2(10));
Assert.AreEqual(610, VbEquiv.Recursion.Fib2(15));
Assert.AreEqual(6765, VbEquiv.Recursion.Fib2(20));
});
}
private void RunTest(string testName, Action tests)
{
var sw = new Stopwatch();
sw.Start();
tests();
sw.Stop();
this.results.Add(new Tuple<string, TimeSpan>(testName, sw.Elapsed));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment