首页 > 解决方案 > 在 IEnumerable 中转换值的最快方法,我错过了 Linq Select 的内容吗?

问题描述

我正在尝试找到对IEnumerable<IPoint>.

IPoint是一个有两个参数decimal Quantity和的接口decimal Price。我还有一个Point实现接口的类,例如:

public class Point : IPoint
{
    public decimal Quantity { get; set; }
    public decimal Price { get; set; }
    public Point(decimal q, decimal p)
    {
        Quantity = q;
        Price = p;
    }
}

我想改变我IEnumerable<IPoint>的结果是一个IEnumerable<IPoint> 地方quantity = price * quantityprice = 1 / price

我比较了使用的结果IEnumerable.SelectforeachIEnumerable.

我随机生成了一个IEnumerable<IPoint> Initial并用以下内容对其进行了转换:

IEnumerable<IPoint> WithSelect = new List<Point>();
IEnumerable<IPoint> WithForeach = new List<Point>();

//With Select
var watch = System.Diagnostics.Stopwatch.StartNew();
WithSelect = Initial.Select(p => new Point(p.Price * p.Quantity, 1 / p.Price));
watch.Stop();
var elapsed1Ms = watch.ElapsedMilliseconds;
var ListTmp = new List<Point>();

//With foreach
watch.Restart();
foreach(var p in Initial)
{
    ListTmp.Add(new Point(p.Price * p.Quantity, 1 / p.Price));
}
WithForeach = ListTmp;
watch.Stop();
var elapsed2Ms = watch.ElapsedMilliseconds;

表现如下:

如果我WithSelect = WithSelect.ToList()有一个更“可用”的类型(即从System.Linq.Enumerable.SelectEnumerableIterator<IPoint, Point>to System.Collections.Generic.List<IPoint>),则执行时间会上升到 ~3900 毫秒(即比每个稍微多一点)。

我会说很好,让我们在Select不转换结果的情况下进行,但我想知道执行时间(0 毫秒,无论 Enumerable 的大小)是否没有隐藏一些东西。这是否意味着仅在我访问这些值时才进行实际计算?这是否也意味着如果我多次访问这些值,我将开始累积计算时间?还是我不应该担心它只是一个非常好的 Linq 优化?

如果 Select 隐藏了一些额外的后期计算时间,是否有替代我尝试过的两个我应该寻找的替代方法?

标签: c#performancelinq

解决方案


推荐阅读