那我就简要介绍下C#并行编程中的PLINQ,并提供两个示例说明。
什么是PLINQ?
PLINQ,全名叫做Parallel LINQ,是C#中的一个并行编程库。它基于LINQ(Language Integrated Query,语言集成查询),可以让我们更方便地执行并行查询和数据操作。相较于手动编写多线程代码,PLINQ让我们的代码更加容易编写和维护,从而大大提升了开发效率。
如何使用PLINQ?
PLINQ相较于普通LINQ来说,只有一些简单的区别。主要包含两个方面:
- 引入System.Linq.Parallel命名空间(using System.Linq.Parallel;)
- 在查询语句中添加AsParallel()方法
下面是一个简单的示例,如何使用PLINQ对一个数组进行并行查询:
using System;
using System.Linq;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
int[] numbers = Enumerable.Range(0, 1000000).ToArray();
var parallelQuery = from item in numbers.AsParallel()
where item % 2 == 0
select item;
parallelQuery.ForAll(Console.WriteLine);
}
}
上述代码中,我们首先创建了一个int类型的数组numbers,其中存储了从0到999,999的所有数字。接着,我们对数组进行了一个PLINQ查询,筛选出其中所有能被2整除的数字。最后,我们使用了ForAll()方法将查询结果逐个打印到控制台上。
需要注意的是,虽然PLINQ可以让我们的查询获得并行处理的优势,但并不是所有情况下都适用。因为并行处理的消耗和开销也非常高,因此只有在处理大量数据时才能发挥出PLINQ的优势。
下面再给出一个示例,说明PLINQ在一些特定的场景中可以带来更大的优势。
示例2:PLINQ在GroupBy操作中的优势
在LINQ中,我们经常需要对数据进行分组操作,GroupBy便是一个常见的操作。在这个操作中,PLINQ可以发挥更大的优势。
举个例子,我们现在有一个数组,其中存储了1000万条数据,每条数据包含了一个日期和一个价格。我们需要根据日期将相同日期的价格进行合并,最后得到每一天的总价。对于这种需求,普通的LINQ查询可以完成,但需要比较长的时间。
下面是普通的LINQ代码示例:
using System;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var data = GenerateData(10000000);
var query = from item in data
group item by item.Date into g
select new
{
Date = g.Key,
TotalPrice = g.Sum(x => x.Price)
};
foreach (var item in query)
{
Console.WriteLine("{0:yyyy-MM-dd}: {1}", item.Date, item.TotalPrice);
}
}
static Data[] GenerateData(int count)
{
var random = new Random();
var startDate = new DateTime(2019, 1, 1);
var data = Enumerable.Range(0, count).Select(x =>
{
var date = startDate.AddDays(random.Next(365));
var price = random.Next(1000);
return new Data(date, price);
}).ToArray();
return data;
}
}
class Data
{
public DateTime Date { get; set; }
public int Price { get; set; }
public Data(DateTime date, int price)
{
this.Date = date;
this.Price = price;
}
}
我们先生成了包含了1000万条数据的数组,然后对它进行了一个GroupBy的操作,根据日期对数据进行分组,然后再对每一组数据求和。最后,我们将结果逐一输出到控制台上。
上述代码的运行时间比较长,我们需要花费几秒钟的时间才能看到结果。接下来,我们看看PLINQ如何处理这个问题。
using System;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var data = GenerateData(10000000);
var query = from item in data.AsParallel()
group item by item.Date into g
select new
{
Date = g.Key,
TotalPrice = g.Sum(x => x.Price)
};
foreach (var item in query)
{
Console.WriteLine("{0:yyyy-MM-dd}: {1}", item.Date, item.TotalPrice);
}
}
static Data[] GenerateData(int count)
{
var random = new Random();
var startDate = new DateTime(2019, 1, 1);
var data = Enumerable.Range(0, count).Select(x =>
{
var date = startDate.AddDays(random.Next(365));
var price = random.Next(1000);
return new Data(date, price);
}).ToArray();
return data;
}
}
class Data
{
public DateTime Date { get; set; }
public int Price { get; set; }
public Data(DateTime date, int price)
{
this.Date = date;
this.Price = price;
}
}
我们只需要在查询语句中添加AsParallel()方法,便可以让PLINQ自动对数据进行并行处理。此时,我们再次运行代码,发现PLINQ在处理1000万条数据的时候,表现得比普通LINQ要快不少。
总结
PLINQ是C#中的一个非常有用的并行编程库,在处理大量数据的时候可以带来很大的优势。当然,PLINQ并不能适用于所有情况,我们需要根据具体情况来使用。在使用PLINQ时,需要注意几个问题:
- 不要滥用PLINQ,只有输入数据量比较大的情况下才适用
- PLINQ的代价非常大,只有在并行处理的性能提升至少能够弥补代价时才能使用
- 可以通过适当调整一些参数来优化PLINQ在具体场景下的性能表现,在相应场景下对PLINQ进行定制化编程。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#并行编程之PLINQ(并行LINQ) - Python技术站