Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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
用LINQ替换foreach_Linq_C# 4.0 - Fatal编程技术网

用LINQ替换foreach

用LINQ替换foreach,linq,c#-4.0,Linq,C# 4.0,我有一些非常简单的代码,我正在尝试使用LINQ而不是标准代码以稍微快一点的速度运行(代码中有很多这样的小类型的调用,这似乎会减慢速度) 问题是,我在LINQ之外有一个变量,LINQ查询的结果需要添加它 原始代码如下所示 double total = 0 foreach(Crop c in p.Crops) { if (c.CropType.Type == t.Type) total += c.Area; } return total; 这种方法在循环开始变大之前不会变慢,

我有一些非常简单的代码,我正在尝试使用LINQ而不是标准代码以稍微快一点的速度运行(代码中有很多这样的小类型的调用,这似乎会减慢速度)

问题是,我在LINQ之外有一个变量,LINQ查询的结果需要添加它

原始代码如下所示

double total = 0
foreach(Crop c in p.Crops)
{
    if (c.CropType.Type == t.Type)
       total += c.Area;
}
return total;

这种方法在循环开始变大之前不会变慢,然后在手机上变慢。这类代码可以移动到一个相对快速和简单的LINQ吗?

看起来您可以使用sum:(编辑:我的语法错了)

或以扩展方法格式:

total = p.Crops.Where(c => c.CropType.Type == t.Type).Sum(c => c.area);
至于有人说LINQ不会表现得更好你的证据呢?(以下内容基于?我在linqpad中运行了以下内容:(您需要下载并引用它才能运行)

void Main()
{
//Nbuilder用于创建样本数据块
//http://nbuilder.org
var crops=Builder.CreateListOfSize(1000000.Build();
var t=新作物();
t、 Type=Type.grain;
双倍合计=0;
var sw=新秒表();
sw.Start();
foreach(作物中的作物c)
{
if(c.Type==t.Type)
总面积+=c.面积;
}
sw.Stop();
total.Dump(“For循环总计:”);
sw.elapsedmillesons.Dump(“对于循环经过的时间:”);
sw.Restart();
var结果=作物。其中(c=>c.Type==t.Type)。总和(c=>c.area);
sw.Stop();
结果.转储(“LINQ总计:”);
sw.elapsedmillesons.Dump(“LINQ运行时间:”);
sw.Restart();
var result2=(来自作物中的c)
其中c.Type==t.Type
选择c.area).Sum();
Dump(“LINQ(sugar语法)total:”;
sw.elapsedmillesons.Dump(“LINQ(糖语法)运行时间:”);
}
公共枚举类型
{
小麦
粮食
玉米
玉米
棉
}
公营作物
{
公共字符串名称{get;set;}
公共类型类型{get;set;}
公共双区;
}
结果对LINQ有利:

循环总计:99999900000

循环运行时间:25

LINQ总计:99999900000

LINQ运行时间:17

LINQ(糖语法)总计:99999900000

LINQ(糖语法)运行时间:17


看起来您可以使用sum:(编辑:我的语法错误)

或以扩展方法格式:

total = p.Crops.Where(c => c.CropType.Type == t.Type).Sum(c => c.area);
至于有人说LINQ不会表现得更好,你的证据在哪里?(以下是基于?我在linqpad中运行了以下内容:(你需要下载并参考才能运行它)

void Main()
{
//Nbuilder用于创建样本数据块
//http://nbuilder.org
var crops=Builder.CreateListOfSize(1000000.Build();
var t=新作物();
t、 Type=Type.grain;
双倍合计=0;
var sw=新秒表();
sw.Start();
foreach(作物中的作物c)
{
if(c.Type==t.Type)
总面积+=c.面积;
}
sw.Stop();
total.Dump(“For循环总计:”);
sw.elapsedmillesons.Dump(“对于循环经过的时间:”);
sw.Restart();
var结果=作物。其中(c=>c.Type==t.Type)。总和(c=>c.area);
sw.Stop();
结果.转储(“LINQ总计:”);
sw.elapsedmillesons.Dump(“LINQ运行时间:”);
sw.Restart();
var result2=(来自作物中的c)
其中c.Type==t.Type
选择c.area).Sum();
Dump(“LINQ(sugar语法)total:”;
sw.elapsedmillesons.Dump(“LINQ(糖语法)运行时间:”);
}
公共枚举类型
{
小麦
粮食
玉米
玉米
棉
}
公营作物
{
公共字符串名称{get;set;}
公共类型类型{get;set;}
公共双区;
}
结果对LINQ有利:

循环总计:99999900000

循环运行时间:25

LINQ总计:99999900000

LINQ运行时间:17

LINQ(糖语法)总计:99999900000

LINQ(糖语法)运行时间:17


优化这一点的主要方法是改变
p
,这可能是可能的,也可能是不可能的

假设
p
p
,如下所示:

internal sealed class P
{
   private readonly List<Crop> mCrops = new List<Crop>();

   public IEnumerable<Crop> Crops { get { return mCrops; } }

   public void Add(Crop pCrop)
   {
      mCrops.Add(pCrop);
   }
}
然后,您的代码会变成:

double total = 0
foreach(Crop crop in p.GetCropsByType(t.Type))
   total += crop.Area;

return total;
另一种更快的可能性是:

internal sealed class P
{
   private readonly List<Crop> mCrops = new List<Crop>();

   private double mTotalArea;

   public IEnumerable<Crop> Crops { get { return mCrops; } }

   public double TotalArea { get { return mTotalArea; } }

   public void Add(Crop pCrop)
   {   
      mCrops.Add(pCrop);
      mTotalArea += pCrop.Area;
   }
}

您也可以考虑将代码< >庄稼> /代码>数据的代码提取到一个单独的类,这取决于什么是<代码> p>代码> .p/> 。优化这个的主要方式将改变<代码> p>代码>,这可能或不可能。

假设
p
p
,如下所示:

internal sealed class P
{
   private readonly List<Crop> mCrops = new List<Crop>();

   public IEnumerable<Crop> Crops { get { return mCrops; } }

   public void Add(Crop pCrop)
   {
      mCrops.Add(pCrop);
   }
}
然后,您的代码会变成:

double total = 0
foreach(Crop crop in p.GetCropsByType(t.Type))
   total += crop.Area;

return total;
另一种更快的可能性是:

internal sealed class P
{
   private readonly List<Crop> mCrops = new List<Crop>();

   private double mTotalArea;

   public IEnumerable<Crop> Crops { get { return mCrops; } }

   public double TotalArea { get { return mTotalArea; } }

   public void Add(Crop pCrop)
   {   
      mCrops.Add(pCrop);
      mTotalArea += pCrop.Area;
   }
}

您也可以考虑将代码< >庄稼> /代码>数据的代码提取到一个单独的类,这取决于什么是<代码> p>代码> .< /p> < p>这是一个非常直接的和,所以我怀疑您会从使用LINQ .< 关于这里的设置,您没有告诉我们太多,但这里有一个想法。如果

p.Crops
很大,并且序列中只有少量的项目是所需的类型,您可以构建另一个序列,其中只包含您需要的项目


我假设您在插入
p.Crops
时知道类型。如果是这种情况,您可以轻松地在另一个集合中插入相关项,并将其用于求和循环。这将减少N并消除比较。它仍然是O(N)尽管如此。

这是一个相当直接的总数,所以我怀疑您是否会从使用LINQ中看到任何好处

关于这里的设置,您没有告诉我们太多,但这里有一个想法。如果
p.Crops
很大,并且序列中只有少量的项目是所需的类型,您可以构建另一个序列,其中只包含您需要的项目

我假设您在插入
p.Crops
时知道类型