当前位置 : 主页 > 网络安全 > 测试自动化 >

Linq IEnumerable扩展方法 – 如何提高性能?

来源:互联网 收集:自由互联 发布时间:2021-06-22
我编写了以下扩展方法,该方法查找满足传递给它的谓词的连续项目序列.序列中连续项的数量由参数’sequenceSize确定. 作为一个例子,我可能有一个IEnumerable的整数,我想找到10个大于100的连
我编写了以下扩展方法,该方法查找满足传递给它的谓词的连续项目序列.序列中连续项的数量由参数’sequenceSize确定.

作为一个例子,我可能有一个IEnumerable的整数,我想找到10个大于100的连续值.这个扩展方法将确定是否存在这样的序列.

这种方法效果很好.但是,由于它必须做的事情,如果IEnumerable中有相当数量的元素,它可能会很慢,因为它必须从第一个元素开始,查找满足谓词的连续值,然后转到第二个元素并执行相同的等

我正在寻找有关如何提高速度的建议.我尝试使用AsParallel(),但没有影响.

public static IEnumerable<IEnumerable<T>> FindSequenceConsecutive<T>(this IEnumerable<T> sequence, 
                                                                     Predicate<T> predicate, 
                                                                     int sequenceSize)
{
    IEnumerable<T> current = sequence;

    while (current.Count() > sequenceSize)
    {
        IEnumerable<T> window = current.Take(sequenceSize);

        if (window.Where(x => predicate(x)).Count() >= sequenceSize)
            yield return window;

        current = current.Skip(1);
    }
}
我相信这个解决方案将提供最佳性能,并且随着序列变大而更好地扩展,因为它不会分配任何额外的缓冲区(列表或队列),也不必将结果转换为List或对其进行任何计数.结果缓冲区.另外,它只迭代序列一次.

public static IEnumerable<IEnumerable<T>> FindSequenceConsecutive<T>(this IEnumerable<T> sequence,
    Predicate<T> predicate, int sequenceSize)
{
    IEnumerable<T> window = Enumerable.Repeat(default(T), 0);

    int count = 0;

    foreach (var item in sequence)
    {
        if (predicate(item))
        {
            window = window.Concat(Enumerable.Repeat(item, 1));
            count++;

            if (count == sequenceSize)
            {
                yield return window;
                window = window.Skip(1);
                count--;
            }
        }
        else
        {
            count = 0;
            window = Enumerable.Repeat(default(T), 0);
        }                
    }
}
网友评论