Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ vs foreach vs性能测试结果_C#_Performance_Linq_For Loop_Foreach - Fatal编程技术网

C# LINQ vs foreach vs性能测试结果

C# LINQ vs foreach vs性能测试结果,c#,performance,linq,for-loop,foreach,C#,Performance,Linq,For Loop,Foreach,有人能解释一下这些结果吗? 我知道有重复的问题,但我还没有找到一个与我的结果得出相同结论的问题:o using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SpeedTest { class Person {

有人能解释一下这些结果吗? 我知道有重复的问题,但我还没有找到一个与我的结果得出相同结论的问题:o

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpeedTest
{
    class Person
    {    
        public Person(string name)
        {
            this.Name = name;
        }

        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var people = new List<Person>();
            AddTwins("FRANCISCO", people);
            var stopwatch = new Stopwatch();

            string name = "OCSICNARF";

            long linqTime = 0L;
            long foreachTime = 0L;
            long forTime = 0L;

            stopwatch.Start();
            Person person0;
            var result = from person in people
                         where person.Name == name
                         select person;
            person0 = result.First();
            linqTime = stopwatch.ElapsedMilliseconds;
            stopwatch.Restart();
            Person person1;
            foreach (Person p in people)
            {
                if (p.Name == name)
                {
                    person1 = p;
                    break;
                }
            }
            foreachTime = stopwatch.ElapsedMilliseconds;
            stopwatch.Restart();
            Person person2;
            for (int i = 0; i < people.Count; i++)
            {
                if (people[i].Name == name)
                {
                    person2 = people[i];
                    break;
                }
            }
            forTime = stopwatch.ElapsedMilliseconds;
            stopwatch.Stop();

            Console.WriteLine(string.Format("LINQ took {0}ms", linqTime));
            Console.WriteLine(string.Format("FOREACH took {0}ms", foreachTime));
            Console.WriteLine(string.Format("FOR took {0}ms", forTime));
        }

        static void AddTwins(string name, List<Person> people)
        {
            AddTwins(people, name, "");
        }

        private static void AddTwins(List<Person> people, string choices, string chosen)
        {
            if (choices.Length == 0)
            {
                people.Add(new Person(chosen));
            }
            else
            {
                for (int i = 0; i < choices.Length; i++)
                {
                    // choose
                    char c = choices[i];
                    string choose1 = choices.Substring(0, i);
                    string choose2 = choices.Substring(i + 1);
                    choices = choose1 + choose2;

                    // explore
                    AddTwins(people, choices, chosen + c);

                    // Unchoose
                    string unchoose1 = choices.Substring(0, i);
                    string unchoose2 = choices.Substring(i);
                    choices = unchoose1 + c + unchoose2;
                }
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间速度测试
{
班主任
{    
公众人物(字符串名称)
{
this.Name=Name;
}
公共字符串名称{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
var people=新列表();
AddTwins(“FRANCISCO”,人物);
var stopwatch=新秒表();
string name=“OCSICNARF”;
长linqTime=0L;
长前驱时间=0L;
长时间=0L;
秒表。开始();
个人0;
var结果=从人到人
其中person.Name==Name
选择人员;
person0=结果。第一个();
linqTime=stopwatch.ElapsedMilliseconds;
stopwatch.Restart();
个人1;
foreach(人员中的人员p)
{
如果(p.Name==Name)
{
人1=p;
打破
}
}
foreachTime=stopwatch.ElapsedMilliseconds;
stopwatch.Restart();
个人2;
for(int i=0;i

您永远不会执行
LINQ
查询,您只是创建它。您应该使用
ToList
ToArray
方法强制迭代,可能不会得到不同的结果,因为
LINQ
也使用
foreach
循环

编辑
LINQ
需要多一点时间,因为您正在迭代所有项目。但是在你的另外两个循环中,你一找到匹配的就打破了循环。尝试使用
FirstOrDefault
而不是
Where
,您应该会得到相同(或类似)的结果


linq one没有花费时间,因为查询从未实际计算过

对于大多数操作,在有人开始枚举结果之前,它实际上不会做任何事情

如果你加上

result.Count(); // add this line, query will be evaluated
linqTime = stopwatch.ElapsedMilliseconds;
stopwatch.Restart();

然后我很确定linq的结果是非零的。

显然重要的是,Sum必须在堆上存储列表枚举器的装箱实例,并使用该堆对象来迭代列表。内联foreach和for循环都避免了这种情况;前者是因为List的公共GetEnumerator方法返回值类型。如果将对人的引用存储在
IEnumerable
变量中,则foreach循环需要更长的时间才能获得结果


此外,linq必须为where迭代器和传递给它的委托创建对象,并且它执行更多的空检查,以便在任何参数为空时抛出信息性异常。这可以解释linq代码所需的其他额外时间。

我的错,我刚刚意识到,请看新的结果/代码。是的,我注意到了,但你们对我来说太快了。看看新的结果。如果LINQ查询应该像foreach循环一样有一个foreach,为什么它会慢一些?如果你看一下为它生成的代码,foreach可能是非常“平坦”的,其中生成的代码可能有一些额外的方法调用,以进入/离开foreach,并产生返回的东西,诸如此类的东西。
result.Count(); // add this line, query will be evaluated
linqTime = stopwatch.ElapsedMilliseconds;
stopwatch.Restart();