Let's play spot the WTFs!



  • Found this C# gem and just had to share it. Go ahead, see what you can find.

    public static class Statistics {
    
        public static double StDev(IEnumerable<double> values) {
            List<double> valueList = new List<double>();
            foreach (double value in values) {
                valueList.Add(value);
            }
            return StDev(valueList);
        }
        
        public static double StDev(List<double> values) {
            // Calculate average
            double sum = 0;
            foreach (double value in values) {
                sum += value;
            }
            double average = sum / values.Count;
            
            // Calculate standard deviation
            double stdevSum = 0;
            foreach (double value in values) {
                stdevSum += Math.Pow((value - average), 2);
            }
            return Math.Sqrt(stdevSum / (values.Count - 1));
        }
    }
    

    So, let's see. Discounting the fact that a List<Double> is an IEnumerable<Double> for now, what else?

    • Manually copying every element of an IEnumerable into a List? values.ToList(), done.
    • Manually calculating the sum of a List? values.Sum(), done.
    • Manually calculating the average? Yep, you guessed, values.Average() and done.

    This entire class could be written as:

    public static double StDev(IEnumerable<double> values) {
        double sum = values.Sum();        
        double average = values.Average();
        
        // Calculate standard deviation
        double stdevSum = 0;
        foreach (double value in values) {
            stdevSum += Math.Pow((value - average), 2);
        }
        return Math.Sqrt(stdevSum / (values.Count() - 1));
    }
    

    And that's just off the top of my head. I didn't even double check the StdDev calculation, I'm just assuming that it's wrong at this point (it's specifically supposed to mimic Excel).

    PS I am unaware of any built-in .NET function that will calculate the standard deviation of a collection but if anyone knows feel free to tell me about it.


    Filed under: (Strongly) Typed but not read, overloaded



  • There's one in 4.x in the "EntityFunctions", whatever that is: https://msdn.microsoft.com/en-us/library/Dd382849(v=VS.110).aspx



  • var average = values.Average(); // precalculating average to O(n) it. Not sure if this would be optimized out.
    return Math.Sqrt(values.Sum(x => Math.Pow((x - average), 2)) / (values.Length - 1));
    


  • I'll be goddamned. Not sure what the EntityFunctions namespace is but still good to know (this snippet was from a project targeting 3.5 so they get a pass on that but still thanks for the info).


    Filed under: worst of the worst



  • And you go to hell for finding a better solution than what I took 10 seconds to come up with.



  • It's what Microsoft is doing instead of adding .NET support for DirectShow.

    @mikeTheLiar said:

    And you go to hell for finding a better solution than what I took 10 seconds to come up with.

    It's the exact same solution.



  • Fewer lines is what I meant. I suppose quality != succinctness



  • Well it is better because his doesn't run a .Sum() for literally no reason at all. I MOCK YOUR CODE



  • I will begin by not reading the thread!

    @mikeTheLiar said:

    List<double> valueList = new List<double>();
    foreach (double value in values) {
    valueList.Add(value);
    }

    1. Java braces.
    2. Copying a list in a terribly inefficient way.

    @mikeTheLiar said:

    public static double StDev(List<double> values) {

    An overload of a thing with a terrible abbreviated name, where you already have one that takes a less specific type.

    @mikeTheLiar said:

    stdevSum

    Lern2Camel



  • true.

    Mine isn't clear what it is doing, at all.

    I just like LINQ a lot, and it's abilities to do transforms.

    The problem is that if you want to comment on it, you have to do a lot of /* */

    var average = values.Average(); // precalculating average to O(n) it. Not sure if this would be optimized out.
    return Math.Sqrt(values.Sum(x => Math.Pow((x - average), 2) /*some comment*/) / (values.Length - 1));
    


  • So your plan was to basically plagiarize my post but be even more pedantic. I don't know who you are but I like you and hate you at the same time.



  • AFAIK Math.Pow doesn't have an (double, int) overload, and logarithms are slow. So I wonder how much more efficient it would be to use (value - average) * (value - average) instead.

    To add just a little bit to efficiency, we could make use of the equivalence

    <(x - <x>)^2> = <x^2> - <x>^2

    And the -1 in the denominator
    (values.Count - 1)
    means it is the standard deviation of a sample. If we've got the entire list of values, we have to omit the -1. So we might add an optional argument to the function (overload) or define a function StDevP (as in the two functions System.Data.Objects.EntityFunction.StandardDeviation and System.Data.Objects.EntityFunction.StandardDeviationP).

    .
    .
    .
    .
    .
    .
    .
    .
    .


  • Discourse touched me in a no-no place

    @PWolff said:

    Math.Pow doesn't have an (double, int) overload

    It might at the native code issuing level, but it's not really all that valuable except when working with small literal exponents (when an optimal multiplication sequence can be used — this has been extensively studied as an interesting NP-Complete problem). For exponents of greater than about 16, or anything non-literal, it's usual to just fall back to simple algorithms using shifting and multiplies; they're non-optimal, but easy to code correctly.

    I don't know if the .NET runtime actually bothers. C++ compilers do…




Log in to reply