c# - 在 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 * quantity
和price = 1 / price
我比较了使用的结果IEnumerable.Select
和foreach
对IEnumerable
.
我随机生成了一个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;
表现如下:
foreach
: 1M 点 ~460 ms 和 10M 点 ~3800msSelect
: 1M 和 10M 点为 0ms....
如果我WithSelect = WithSelect.ToList()
有一个更“可用”的类型(即从System.Linq.Enumerable.SelectEnumerableIterator<IPoint, Point>
to System.Collections.Generic.List<IPoint>
),则执行时间会上升到 ~3900 毫秒(即比每个稍微多一点)。
我会说很好,让我们在Select
不转换结果的情况下进行,但我想知道执行时间(0 毫秒,无论 Enumerable 的大小)是否没有隐藏一些东西。这是否意味着仅在我访问这些值时才进行实际计算?这是否也意味着如果我多次访问这些值,我将开始累积计算时间?还是我不应该担心它只是一个非常好的 Linq 优化?
如果 Select 隐藏了一些额外的后期计算时间,是否有替代我尝试过的两个我应该寻找的替代方法?
解决方案
推荐阅读
- javascript - 从数组中获取出现的地图
- sed - 如何sed替换文本块
- jquery - 从链接打开 pdf (colissimo)
- angular - 在 Angular 10 中单独的谷歌登录
- django - 如果图像源存储在数据库中,Django 从 s3 存储桶获取图像
- regex - 使用 ColdFusion 从任何字符串生成首字母缩略词的正则表达式
- python - 错误数据类型的 Python 比较运算符
- tableview - TableView 不使用滚动条显示所有列
- sql - MS Access:为什么我的报告不显示正确的标题?
- python - 使用日期时间索引和重复时间戳滚动