我是LINQ的新手。我想知道“日期”的最高值是什么,首选哪种方法?
var ma1x= spResult.Where(p =>p.InstrumentId== instrument).OrderByDescending(u => int.Parse(u.Date)).FirstOrDefault();
var max2= spResult.Where(p =>p.InstrumentId== instrument).Max(u => int.Parse(u.Date));
Max或OrderByDescending吗?
答案 0 :(得分:2)
Max
总是会更好,因为Max
具有语义和意义。
Enumerable.Max方法
以一系列值返回最大值。
您想要最大值吗?使用Max
。您要订购吗?使用OrderBy
。下一位开发人员将感谢您。引用马丁·福勒的话:
任何傻瓜都可以编写计算机可以理解的代码。优秀的程序员编写人类可以理解的代码。
如果您真的想至少使用OrderBy
来扮演Max
的角色,则将orderby和第一个包装在一个有意义的名称的方法中。类似于... Max
。太好了,现在您有了一个有意义的OrderBy。
让我们看看这个自定义Max
的工作方式。
Enumerable.Max
使用O(n ^ 2)的快速排序时, OrderBy
应该为O(n)。因此,自定义最大值比标准最大值差。
享受绩效奖金,并获得Enumerable.Max
。对于开发人员和计算机都更好。
编辑:
检查Marco的answer,看看他们在实践中的表现如何。 race of horses总是一个好主意,知道哪个速度更快。
答案 1 :(得分:1)
.Max()
应该更快。首先,该方法的语义更加清晰,您的同事将知道您的调用会做什么。
我已经比较了AdventureWorks2014数据库中的两个选项以及LinqPad中的以下调用:
var times = new List<long>();
for(var i = 0; i < 1000; i++) {
Stopwatch sw = Stopwatch.StartNew();
var max2= SalesOrderHeaders.Max(u => u.OrderDate);
long elapsed = sw.ElapsedMilliseconds;
times.Add(elapsed);
}
var averageElapsed = times.Sum (t => t) / times.Count();
averageElapsed.Dump(" ms");
生成的SQL:
SELECT MAX([t0].[OrderDate]) AS [value]
FROM [Sales].[SalesOrderHeader] AS [t0]
GO
结果:
5毫秒
var times = new List<long>();
for(var i = 0; i < 1000; i++) {
Stopwatch sw = Stopwatch.StartNew();
var max1 = SalesOrderHeaders.OrderByDescending(u => u.OrderDate).FirstOrDefault();
long elapsed = sw.ElapsedMilliseconds;
times.Add(elapsed);
}
var averageElapsed = times.Sum (t => t) / times.Count();
averageElapsed.Dump(" ms");
生成的SQL:
SELECT TOP (1) [t0].[SalesOrderID], [t0].[RevisionNumber], [t0].[OrderDate], [t0].[DueDate], [t0].[ShipDate], [t0].[Status], [t0].[OnlineOrderFlag], [t0].[SalesOrderNumber], [t0].[PurchaseOrderNumber], [t0].[AccountNumber], [t0].[CustomerID], [t0].[SalesPersonID], [t0].[TerritoryID], [t0].[BillToAddressID], [t0].[ShipToAddressID], [t0].[ShipMethodID], [t0].[CreditCardID], [t0].[CreditCardApprovalCode], [t0].[CurrencyRateID], [t0].[SubTotal], [t0].[TaxAmt], [t0].[Freight], [t0].[TotalDue], [t0].[Comment], [t0].[rowguid] AS [Rowguid], [t0].[ModifiedDate]
FROM [Sales].[SalesOrderHeader] AS [t0]
ORDER BY [t0].[OrderDate] DESC
GO
结果:
28ms
结论:Max()
更简洁,更快捷!
答案 2 :(得分:0)
纯粹是投机性的,但我会想象max2。它只是遍历每个项目,并检查该值是否高于上一个。 而max1正在检查哪个较高并重新排序。即使只是移动指针(而不是移动值),这仍然需要更多工作。
答案 3 :(得分:0)
Max
方法优于FirstOrDefault
,它们都将结果发送为true,但是Max的性能很好。
此代码:
var ma1x= spResult.Where(p =>p.InstrumentId== instrument).OrderByDescending(u => int.Parse(u.Date)).FirstOrDefault();
首先检查您的状况,然后根据您的状况对它们进行排序,然后将其选择并采取更多措施来找到您的结果。