对,
cylindre
是3D圆柱体,我想知道里面是哪一点。没有LINQ的版本1
/>
for (int i = 0; i < fpc.Vertices.Length; i++)
{
if (cylindre.IsPointInside(fpc.Vertices[i]))
listPoint.Add(fpc.Vertices[i]);
}
版本2,带有LINQ
var insidePoint =
from pt1 in fpc.Vertices
where cylindre.IsPointInside(pt1)
select pt1;
foreach (Point3D pt2 in insidePoint)
{
listPoint.Add(pt2);
}
#1 楼
就像Q4312079Q一样,LINQ会在引擎上遍历整个集合。 LINQ和foreach的区别在于LINQ将推迟执行直到迭代开始。性能方面的知识请看这篇博客文章。
评论
\ $ \ begingroup \ $
关于该链接的说明。该链接正在处理从列表中删除元素。它使用一个for循环,然后与一个双foreach循环和一个LINQ / foreach组合进行对比。这不是一个公平的比较。
\ $ \ endgroup \ $
– pstrjds
2012年8月9日13:40
\ $ \ begingroup \ $
此答案发布时,该链接已有3年历史,现在已超过11年。
\ $ \ endgroup \ $
–是
20年8月2日在6:59
\ $ \ begingroup \ $
链接不再有效
\ $ \ endgroup \ $
–Chase Florell
20-09-17在15:34
#2 楼
就像已经说过的那样,for循环很有可能会表现得更好,但是您仍然可以清理一些代码:for (int i = 0; i < fpc.Vertices.Length; i++)
{
if (cylindre.IsPointInside(fpc.Vertices[i]))
listPoint.Add(fpc.Vertices[i]);
}
可以成为:
foreach (var vertice in fpc.Vertices)
{
if (cylindre.IsPointInside(vertice))
listPoint.Add(vertice);
}
编辑:根据性能问题。该代码将在LINQPad中运行。我发现foreach版本的性能比for循环好几毫秒。
var elements = Enumerable.Range(0, 4000000).Select(x => true).ToArray();
var sw = new Stopwatch();
var result = new List<bool>();
int trueCount = 0;
sw.Start();
for(int i=0; i < elements.Length; ++i)
{
if (elements[i])
{
++trueCount;
result.Add(elements[i]);
}
}
sw.Stop();
sw.ElapsedMilliseconds.Dump();
sw.Reset();
trueCount = 0;
result = new List<bool>();
sw.Start();
foreach(var element in elements)
{
if (element)
{
++trueCount;
result.Add(element);
}
}
sw.Stop();
sw.ElapsedMilliseconds.Dump();
EDIT2-关于链接似乎表明在foreach循环中性能如此差劲
链接(http://www.schnieds.com/2009/03/linq-vs-foreach-vs-for-loop-performance.html)涉及从列表中删除元素。在您具有通用列表的情况下,通过for循环删除元素通常不是最佳方法。更好的方法是使用RemoveAll方法。 RemoveAll将删除所有与谓词匹配的元素,然后合并列表(与RemoveAt相反),RemoveAll需要将所有元素移到已删除元素上方。对于删除的性能比较,请参见以下代码(再次,可以在LINQPad中运行)。在我的测试中,RemoveAll的运行速度大约快了250倍。
var elements = Enumerable.Range(0, 100000).Select(x => x % 2 == 0).ToArray();
var sw = new Stopwatch();
var source = new List<bool>(elements);
sw.Start();
for(int i=0; i < source.Count; ++i)
{
if (!source[i])
{
source.RemoveAt(i);
--i;
}
}
sw.Stop();
sw.ElapsedMilliseconds.Dump();
int count = source.Count;
sw.Reset();
source = new List<bool>(elements);
sw.Start();
source.RemoveAll((bool x) => {return x;});
sw.Stop();
sw.ElapsedMilliseconds.Dump();
评论
\ $ \ begingroup \ $
如Xharze的链接schnieds.com/2009/03/…所述,用foreach代替for循环会降低性能。
\ $ \ endgroup \ $
– Goldoldak84
2012年8月9日13:09
\ $ \ begingroup \ $
@ Goldorak84-如果查看该链接的代码示例,您将看到在foreach和LINQ情况下,代码遍历该列表两次,而for情况仅遍历该列表两次。该链接正在处理从列表中删除项目,并且可以使用RemoveAll编写而没有循环,这甚至比for循环还要快。
\ $ \ endgroup \ $
– pstrjds
2012年8月9日13:29
\ $ \ begingroup \ $
@pstrjds-对不起,您说得很对。我修改了代码示例,将foreach和linq列表删除机制应用于for循环。 for和foreach之间的区别几乎不明显。
\ $ \ endgroup \ $
– Goldoldak84
2012年8月9日14:51
#3 楼
更新:如果目标是.net 4或更高版本,则可以使用:
Parallel.ForEach()
或
RemoveAll().Parallel();
它们应该比其他方法更快。
评论
\ $ \ begingroup \ $
List
\ $ \ endgroup \ $
– Mathieu Guindon♦
14年4月15日在22:13
#4 楼
我认为它不会在LINQ上运行得更快。仍然必须在每个顶点上调用函数cylindre.IsPointInside
。
评论
这可能会有所帮助:developers.stackexchange.com/questions/80084/…@ANeves有趣的文章。我认为我的问题还为时过早,因为这是必需的,而且非常重要,因为每个用户每天要完成500次。我没有真实数据的唯一原因是最终产品尚未准备就绪,但我可以确定它会更大,因此此时的优化非常重要。我也在考虑其他改进功能的方法,但是linq和foreach之间的区别让我很感兴趣。
您是否在算法上压缩了每一点性能?您使用哪种数据结构和算法很重要。 .Net的一些高度优化的库将更快地执行一些计算。另外,也许可以同时使用PLINQ并利用多个内核?我也会测量的。
谢谢(你的)信息。实际上,我们已经使用LINQ和foreach创建了一个很小的子集来运行foreach,现在它以超快的速度运行。
在LINQ版本中,您可以考虑使用AddRange()代替foreach。它不会提高性能,但是会使您的代码更具可读性。另外,直接使用Where()会比from / where / select短。