Reputation: 22116
I am working on optimizing for speed a method to calculate a triangle number for ProjectEuler - Problem 12.
I need to somehow be able to initialize the first element in an array:
private static ulong[] numbersArray = new ulong[5000];
One way to calculate a triangle number would be:
public static ulong GetTriangleFormula(ulong n)
{
return n * (n + 1) / 2;
}
But it has a computational complexity somewhere between O(n) and O(n^2) so I was thinking I could trade memory for run speed by computing the numbers recursively and storing the results in a Dictionary/array. Since the triangle numbers will be calculated successively in the final solution it should work.
Computing the n-th triangle number should become a simple sum of numbersArray[n - 2] and n.
Using a Dictionary the computation was much slower for successive triangle number computation from 1 to 1000:
private static Dictionary<ulong, ulong> numbers = new Dictionary<ulong, ulong>() { { 1, 1 } };
public static ulong GetTriangleDictionaryRecursive(ulong n)
{
if (!numbers.ContainsKey(n))
numbers[n] = n + GetTriangleDictionaryRecursive(n - 1);
return numbers[n];
}
I added {1, 1} to the Dictionary so that i wouldn't have to always check at the beginning of the GetTriangleDictionaryRecursive method for the base case:
if(n == 1) return 1;
But the results were that it was about 40 times slower than the formula method.
So now i am trying to write a method using an array of type ulong[] but I do not know how I can initialize only the first element with value 1 (the others being default for ulong 0).
public static ulong GetTriangleArrayRecursive(ulong n)
{
if (numbersArray[n - 1] == 0)
numbersArray[n - 1] = n + GetTriangleArrayRecursive(n - 1);
return numbersArray[n - 1];
}
Thanks for your help! :)
Upvotes: 0
Views: 1563
Reputation: 1503290
I have no idea whether or not it's appropriate for the Euler problem, but in general if I want to do more work than a single simple expression for initialization, I do it like this:
private static readonly ulong[] numbersArray = CreateNumbersArray();
private static ulong[] CreateNumbersArray()
{
ulong[] ret = new ulong[5000];
ret[0] = 1;
return ret;
}
Or you can do it in a static constructor:
private static readonly ulong[] numbersArray;
static FooClass()
{
numbersArray = new ulong[5000];
numbersArray[0] = 1;
}
Are you really sure it's appropriate to make this a static variable, by the way?
Upvotes: 1