C# 哪一个性能更好:foreach()语句还是Where()查询?

C# 哪一个性能更好:foreach()语句还是Where()查询?,c#,linq,C#,Linq,我有一个元素列表,我想根据特定条件将元素过滤到otherlist中。我有两个选择: 使用foreach()语句 List<Address> allAddress = new List<Address>(); List<Address> chaplinAddress = new List<Address>(); foreach (Address item in allAddress) { if (it

我有一个元素列表,我想根据特定条件将元素过滤到otherlist中。我有两个选择:

  • 使用foreach()语句

        List<Address> allAddress = new List<Address>();
        List<Address> chaplinAddress = new List<Address>();
    
        foreach (Address item in allAddress)
        {
            if (item.city.ToUpper() == "CHAPLIN")
            {
                chaplinAddress.Add(item);
            }
        }
    

    List

    您可以使用timer对象检查哪一个更快,但通常LINQ不会比foreach()快,因为它(LINQ语句)也在内部使用循环。另一方面,需要指出的是,LINQ更易于阅读、理解,并且能够减少bug。但是如果您非常关心性能,就不应该使用LINQ


    您可以检查

    您可以使用timer对象来检查哪一个更快,但通常LINQ不会比foreach()快,因为它(LINQ语句)在内部也使用循环。另一方面,需要指出的是,LINQ更易于阅读、理解,并且能够减少bug。但是如果您非常关心性能,就不应该使用LINQ


    您可以检查

    LINQ是否在内部使用循环。。。您可以使用以下工具检查其内部工作方式:

    可枚举。其中

    public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
        if (source == null) throw Error.ArgumentNull("source");
        if (predicate == null) throw Error.ArgumentNull("predicate");
        if (source is Iterator<TSource>) return ((Iterator<TSource>)source).Where(predicate);
        if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate);
        if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate);
        return new WhereEnumerableIterator<TSource>(source, predicate);
    }
    
    (作为一个链接,因为粘贴到这里有点太长了


    使用LINQ时会有一点开销,因为委托调用,但是您根本不应该关心这一点。像这样过早的优化是有害的,而且比它需要的这一点点时间开销更糟糕。

    LINQ在内部使用循环……您可以使用:

    可枚举。其中

    public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
        if (source == null) throw Error.ArgumentNull("source");
        if (predicate == null) throw Error.ArgumentNull("predicate");
        if (source is Iterator<TSource>) return ((Iterator<TSource>)source).Where(predicate);
        if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate);
        if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate);
        return new WhereEnumerableIterator<TSource>(source, predicate);
    }
    
    (作为一个链接,因为粘贴到这里有点太长了


    使用LINQ时会有一点开销,因为委托调用,但是您根本不应该关心这一点。像这样过早的优化是有害的,而且比它所需要的这一点点时间开销更糟糕。

    决定测试这一点。100000000个随机字符串,一个“卓别林”插入

    • foreach循环需要6个滴答声
    • LINQ查询使用了296个刻度
    看起来foreach速度更快

    编辑:做了更科学的研究。在VS之外,在发布模式下运行每个测试1000次

    • 每个循环的平均值为0个刻度
    • lima查询的平均值为4个刻度
    请记住,对于100000000个城市的1000次查找,滴答声是一千万分之一秒,这会产生0.0000004秒的差异


    我认为你是个好人。

    决定测试一下。100000000个随机字符串,插入一个“卓别林”

    • foreach循环需要6个滴答声
    • LINQ查询使用了296个刻度
    看起来foreach速度更快

    编辑:做了更科学的研究。在VS之外,在发布模式下运行每个测试1000次

    • 每个循环的平均值为0个刻度
    • lima查询的平均值为4个刻度
    请记住,对于100000000个城市的1000次查找,滴答声是一千万分之一秒,这会产生0.0000004秒的差异



    我认为你是个好人。

    你可以自己用定时器检查一下。我已经重新表述了这个问题。实际上,我想要的是更好的性能。更好的性能不就是说“哪个更快”的另一种方式吗?不管怎样,这个很简单——你自己检查一下。你为什么要我们这样做?我想这就是定义过早优化的定义。你可以自己用定时器来检查。我已经重新表述了这个问题。实际上我想要的是更好的性能。更好的性能不是说“哪个更快”的另一种方式吗?不管怎样,这个很简单-你自己检查一下。你为什么要我们这样做?我想这就是定义“但如果您非常关心性能,就不应该使用LINQ”错误什么?如果我见过过早优化的例子,除非这是在一个紧密的循环或其他性能热点中,否则我会将LINQ视为一个不成熟的优化-issue@jdphenix:-也许你弄错了,我想说的是LINQ速度较慢,这是由于过度使用。尽管LINQ更易于阅读和维护。“但是如果您非常关心性能,就不应该使用LINQ"错误什么?如果我见过过早优化的例子,除非这是在一个紧密的循环或其他性能热点中,否则我会将LINQ视为一个不成熟的优化-issue@jdphenix:-可能是你弄错了我想说的是LINQ速度较慢,这是由于超负荷。虽然LINQ更易于阅读和维护。但你可能有点问题nchmark.
    10000000
    0
    999999
    ,foreach vs LINQ
    其中
    +
    ToList
    仅获取这些
    i%10==0
    的值。结果?
    foreach
    284ms,LINQ:379ms。发布构建,在vs之外运行。我认为重要的是要意识到,无论我运行多少次,这将是不一致的。您是否作为发行版构建并在IDE之外运行?例如,我将不同的选项推到了它们自己的版本中(相同)方法,现在我得到了998903,LINQ。下一次,1176910,LINQ。只是在VS,13088458,LINQ之外运行了一个发布版本。下一次,244115953,LINQNow,这些是滴答声。我怀疑这在OP的场景中是否有意义。肯定是过早的优化您的基准测试有问题。
    10000000
    ints from
    0
    9999999
    ,foreach vs LINQ
    其中
    +
    ToList
    仅获取
    i%10==0
    的这些。结果?
    foreach
    :284ms,LINQ:379ms。发布版本,在vs之外运行。我认为重要的是要意识到,无论我运行多少次,它都不会保持一致。你知道吗作为发行版构建并在IDE之外运行?例如,我将不同的选项放入它们自己的(相同的)方法中,现在我得到了998903,LINQ。下次,1176910,LINQ。只运行了一个r
    public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
        if (source == null) throw Error.ArgumentNull("source");
        return new List<TSource>(source);
    }