I have a program that calls a method with the linq aggregate a lot. The purpose is to find the closest value in the list. It currently does it on a List but I need to move the data the double holds into a struct or class. But when I do the program takes almost twice as long to run.
I wrote a sample program below to help illustrate what is going on.
I haven't been programming long so I am sure there is something I am not doing right. Can someone help me understand why its so much slower and is there a way to speed it up? Maybe I shouldn't use linq for this?
    static class Program
    {
        private static readonly List<double> _list = new List<double>();
        private static readonly List<ClassFoo> _classFooList = new List<ClassFoo>();
        private static readonly List<StructFoo> _structFooList = new List<StructFoo>();
        static void Main()
        {
            double _searchVal = 1000.5;
            double _searchCount = 300000;
            
            ClassFoo searchClassFoo = new ClassFoo(_searchVal);
            StructFoo searchStructFoo = new StructFoo(_searchVal);
            for (int i = 0; i < 2000; i++)
            {
                _list.Add(i);
                _classFooList.Add(new ClassFoo(i));
                _structFooList.Add(new StructFoo(i));
            }
            Stopwatch watch;
            Console.WriteLine("double...");
            watch = Stopwatch.StartNew();
            for (int i = 0; i < _searchCount; i++)
            {
                double closest = _list.Aggregate((x, y) => Math.Abs(x - _searchVal) < Math.Abs(y - _searchVal) ? x : y);
            }
            watch.Stop();
            Console.WriteLine(watch.ElapsedMilliseconds);
            Console.WriteLine();
            Console.WriteLine("Struct...");
            watch = Stopwatch.StartNew();
            for (int i = 0; i < _searchCount; i++)
            {
                StructFoo closest = _structFooList.Aggregate((x, y) => Math.Abs(x.Value - searchStructFoo.Value) < Math.Abs(y.Value - searchStructFoo.Value) ? x : y);
            }
            watch.Stop();
            Console.WriteLine(watch.ElapsedMilliseconds);
            Console.WriteLine();
            Console.WriteLine("Class...");
            watch = Stopwatch.StartNew();
            for (int i = 0; i < _searchCount; i++)
            {
                ClassFoo closest = _classFooList.Aggregate((x, y) => Math.Abs(x.Value - searchClassFoo.Value) < Math.Abs(y.Value - searchClassFoo.Value) ? x : y);
            }
            watch.Stop();
            Console.WriteLine(watch.ElapsedMilliseconds);
        }
    }
    readonly struct StructFoo
    {
        public StructFoo(double value) => Value = value;
        public double Value { get; }
        //There will be more properties but not needed for this example.
    }
    class ClassFoo
    {
        public ClassFoo(double value) => Value = value;
        public double Value { get; }
        //There will be more properties but not needed for this example.
    }
Here are my results:
double...
6340
Struct...
11249
Class...
11806
Press any key to continue . . .
