Slope method optimisation
-
I'm trying to optimise the following Slope method so that it runs in as few clock cycles as possible. Any Suggestions?
public static double?\[\] slopeImpl(double?\[\] vals, int offset) { double y = 0; int iterableLength = vals.Length; int numValues = vals.Length; double invNumValues = 1.0 / (vals.Length - offset); double x = (double)(((numValues \* (numValues - 1)) >> 1) - ((offset \* (offset - 1)) >> 1)); for (int i = offset; i < iterableLength; i++) { y += (vals\[i\].GetType() == typeof(System.DBNull)) ? 0.0 : (double)vals\[i\]; } y = y \* invNumValues; double v1 = 0.0; double v2 = 0.0; double v2HalfResult = 0.0; for (int i = offset; i < iterableLength; i++) { v2HalfResult = (i - x); v1 += (v2HalfResult) \* ((double)vals\[i\] - y); v2 += (v2HalfResult) \* (v2HalfResult); } double slope = v1 / v2; double intercept = y - slope \* x; double?\[\] result = new double?\[2\]; result\[0\] = slope; result\[1\] = intercept; return result; }
What I have considered: 1. There are two loops which are iterating the same number of times; however I am not sure if it is possible to use one loop. The second loop is dependant on the value of y which is calculated in the first loop and the line after. 2. Use a table to calculate x which is of the form n(n-1) /2. Possible, however the values array can contain more than 365 elements. Thanks for any help.
My blog:[^]
-
I'm trying to optimise the following Slope method so that it runs in as few clock cycles as possible. Any Suggestions?
public static double?\[\] slopeImpl(double?\[\] vals, int offset) { double y = 0; int iterableLength = vals.Length; int numValues = vals.Length; double invNumValues = 1.0 / (vals.Length - offset); double x = (double)(((numValues \* (numValues - 1)) >> 1) - ((offset \* (offset - 1)) >> 1)); for (int i = offset; i < iterableLength; i++) { y += (vals\[i\].GetType() == typeof(System.DBNull)) ? 0.0 : (double)vals\[i\]; } y = y \* invNumValues; double v1 = 0.0; double v2 = 0.0; double v2HalfResult = 0.0; for (int i = offset; i < iterableLength; i++) { v2HalfResult = (i - x); v1 += (v2HalfResult) \* ((double)vals\[i\] - y); v2 += (v2HalfResult) \* (v2HalfResult); } double slope = v1 / v2; double intercept = y - slope \* x; double?\[\] result = new double?\[2\]; result\[0\] = slope; result\[1\] = intercept; return result; }
What I have considered: 1. There are two loops which are iterating the same number of times; however I am not sure if it is possible to use one loop. The second loop is dependant on the value of y which is calculated in the first loop and the line after. 2. Use a table to calculate x which is of the form n(n-1) /2. Possible, however the values array can contain more than 365 elements. Thanks for any help.
My blog:[^]
Instead of
y += (vals[i].GetType() == typeof(System.DBNull)) ? 0.0 : (double)vals[i];
could be changed to something along the lines of
if (vals[i].HasValue) y += vals[i].Value;
But are there actually any null values? Changing the argument to just a straight out double[] would definitely help
"You get that on the big jobs."
-
I'm trying to optimise the following Slope method so that it runs in as few clock cycles as possible. Any Suggestions?
public static double?\[\] slopeImpl(double?\[\] vals, int offset) { double y = 0; int iterableLength = vals.Length; int numValues = vals.Length; double invNumValues = 1.0 / (vals.Length - offset); double x = (double)(((numValues \* (numValues - 1)) >> 1) - ((offset \* (offset - 1)) >> 1)); for (int i = offset; i < iterableLength; i++) { y += (vals\[i\].GetType() == typeof(System.DBNull)) ? 0.0 : (double)vals\[i\]; } y = y \* invNumValues; double v1 = 0.0; double v2 = 0.0; double v2HalfResult = 0.0; for (int i = offset; i < iterableLength; i++) { v2HalfResult = (i - x); v1 += (v2HalfResult) \* ((double)vals\[i\] - y); v2 += (v2HalfResult) \* (v2HalfResult); } double slope = v1 / v2; double intercept = y - slope \* x; double?\[\] result = new double?\[2\]; result\[0\] = slope; result\[1\] = intercept; return result; }
What I have considered: 1. There are two loops which are iterating the same number of times; however I am not sure if it is possible to use one loop. The second loop is dependant on the value of y which is calculated in the first loop and the line after. 2. Use a table to calculate x which is of the form n(n-1) /2. Possible, however the values array can contain more than 365 elements. Thanks for any help.
My blog:[^]
No you can't avoid the two loops, you need the averages first, then the deviations, which you can't get without knowing the averages first. IMO all you can do is clean up your code a bit, by: - getting rid of the nullables, GetType() and typeof; - not calling vals.Length three times; - returning just the slope as a double; - not calculating the intercept, unless you really need it, and then maybe provide the intercept as an out parameter (this saves the allocation of the double[2] array). BTW: using >>1 to divide by 2 does not really help; compilers are smart enough to emit decent code to divide by 2. BTW2: I have some doubts about the correctness of your line
double x = (double)(((numValues * (numValues - 1)) >> 1) - ((offset * (offset - 1)) >> 1));
it doesn't agree with my intuition, e.g. changing the value of offset from 0 to 1 would not change x at all?? :)Luc Pattyn [My Articles] Nil Volentibus Arduum
-
I'm trying to optimise the following Slope method so that it runs in as few clock cycles as possible. Any Suggestions?
public static double?\[\] slopeImpl(double?\[\] vals, int offset) { double y = 0; int iterableLength = vals.Length; int numValues = vals.Length; double invNumValues = 1.0 / (vals.Length - offset); double x = (double)(((numValues \* (numValues - 1)) >> 1) - ((offset \* (offset - 1)) >> 1)); for (int i = offset; i < iterableLength; i++) { y += (vals\[i\].GetType() == typeof(System.DBNull)) ? 0.0 : (double)vals\[i\]; } y = y \* invNumValues; double v1 = 0.0; double v2 = 0.0; double v2HalfResult = 0.0; for (int i = offset; i < iterableLength; i++) { v2HalfResult = (i - x); v1 += (v2HalfResult) \* ((double)vals\[i\] - y); v2 += (v2HalfResult) \* (v2HalfResult); } double slope = v1 / v2; double intercept = y - slope \* x; double?\[\] result = new double?\[2\]; result\[0\] = slope; result\[1\] = intercept; return result; }
What I have considered: 1. There are two loops which are iterating the same number of times; however I am not sure if it is possible to use one loop. The second loop is dependant on the value of y which is calculated in the first loop and the line after. 2. Use a table to calculate x which is of the form n(n-1) /2. Possible, however the values array can contain more than 365 elements. Thanks for any help.
My blog:[^]
-
Instead of
y += (vals[i].GetType() == typeof(System.DBNull)) ? 0.0 : (double)vals[i];
could be changed to something along the lines of
if (vals[i].HasValue) y += vals[i].Value;
But are there actually any null values? Changing the argument to just a straight out double[] would definitely help
"You get that on the big jobs."
-
No you can't avoid the two loops, you need the averages first, then the deviations, which you can't get without knowing the averages first. IMO all you can do is clean up your code a bit, by: - getting rid of the nullables, GetType() and typeof; - not calling vals.Length three times; - returning just the slope as a double; - not calculating the intercept, unless you really need it, and then maybe provide the intercept as an out parameter (this saves the allocation of the double[2] array). BTW: using >>1 to divide by 2 does not really help; compilers are smart enough to emit decent code to divide by 2. BTW2: I have some doubts about the correctness of your line
double x = (double)(((numValues * (numValues - 1)) >> 1) - ((offset * (offset - 1)) >> 1));
it doesn't agree with my intuition, e.g. changing the value of offset from 0 to 1 would not change x at all?? :)Luc Pattyn [My Articles] Nil Volentibus Arduum