【发布时间】:2011-01-14 09:41:37
【问题描述】:
我有一个困扰我的问题;它被封装为一个新的查询运算符,我做了两个版本,试图看看哪个版本更好。两者的表现都很糟糕。
第一次尝试;声明式风格
public static IEnumerable<IEnumerable<α>> Section<α>(this IEnumerable<α> source, int length)
{
return source.Any()
? source.Take(length).Cons(source.Skip(length).Section(length))
: Enumerable.Empty<IEnumerable<α>>();
}
第二次尝试:命令式“收益回报”风格
public static IEnumerable<IEnumerable<α>> Section<α>(this IEnumerable<α> source, int length)
{
var fst = source.Take(length);
var rst = source.Skip(length);
yield return fst;
if (rst.Any())
foreach (var section in rst.Section(length))
yield return section;
}
事实上,第二次尝试更糟糕,无论是在可读性、组合性还是速度方面。
关于如何优化它的任何线索?
【问题讨论】:
-
我认为第二个更易读恕我直言
-
您能否简要介绍一下您使用 Section 功能的目标是什么?看起来您尝试使用 IEnumerable 并对其进行枚举,每次都会获得一个带有长度项的新 IEnumerable,对吗?
-
Enumerate 是一种扩展方法,它只对自身产生收益,它是一种将值投影到 IEnumerable
中的简单方法;所以假设 x 是一个 int,然后 x.Enumerate() 创建一个 IEnumerable 类型的值,它只有一个值。 -
目标是创建一个排序矩阵,所以如果你有这个 [1, 2, 3, 4] 那么 xs.Section(2) 将产生 [[1, 2], [3 , 4]]
-
Enumerate + Concat 实际上是“Cons”,例如x.Enumerate().Concat(xs) => x.Cons(xs)
标签: c# linq performance optimization linq-to-objects