繁体   English   中英

为什么这个 Linq 在 IEnumerable 上聚合<class.primitive> & I 可枚举<struct.primitive>比 IEnumerable 慢得多<primitive></primitive></struct.primitive></class.primitive>

[英]Why is this Linq Aggregate on IEnumerable<Class.primitive> & IEnumerable<Struct.primitive> much slower than IEnumerable<primitive>

我有一个程序调用一个方法与 linq 聚集了很多。 目的是在列表中找到最接近的值。 它目前在 List 上执行,但我需要将 double 保存的数据移动到结构或 class 中。但是当我这样做时,程序运行的时间几乎是原来的两倍。

我在下面写了一个示例程序来帮助说明发生了什么。

我编程时间不长,所以我确信有些事情我做得不对。 有人能帮我理解为什么它这么慢,有没有办法加快速度? 也许我不应该为此使用 linq?

    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.
    }

这是我的结果:

double...
6340

Struct...
11249

Class...
11806
Press any key to continue . . .

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM