LINQ

确定相同类型的两个实例的属性值是否相等

public static bool PublicInstancePropertiesEqual<T>(this T self, T to, params string[] ignore) where T : class
{
    if (self == null || to == null)
    {
        return self == to;
    }

    // Selects the properties which have unequal values into a sequence of those properties.
    var unequalProperties = from property in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                            where !ignore.Contains(property.Name)
                            let selfValue = property.GetValue(self, null)
                            let toValue = property.GetValue(to, null)
                            where !Equals(selfValue, toValue)
                            select property;
    return !unequalProperties.Any();
}

 

PLINQ

ParallelEnumerable 运算符描述
AsParallel PLINQ 的入口点。 指定如果可能,应并行化查询的其余部分。
AsSequential 指定查询的其余部分应像非并行的 LINQ 查询一样按顺序运行。
AsOrdered 指定 PLINQ 应为查询的其余部分保留源序列的排序,或直到例如通过使用 orderby(在 Visual Basic 中为 Order By)子句更改排序为止。
AsUnordered 指定保留源序列的排序不需要查询其余部分的 PLINQ。
WithCancellation 指定 PLINQ 应定期监视请求取消时所提供的取消标记的状态以及取消执行。
WithDegreeOfParallelism 指定 PLINQ 应用于并行化查询的处理器的最大数量。
WithMergeOptions 提供有关 PLINQ 应如何(如果可能)将并行结果合并回使用线程上的一个序列的提示。
WithExecutionMode 指定 PLINQ 应如何并行化查询(即使是当默认行为是按顺序运行查询时)。
ForAll 一种多线程枚举方法,与循环访问查询结果不同,它允许在不首先合并回使用者线程的情况下并行处理结果。
Aggregate 重载 对于 PLINQ 唯一的重载,它启用对线程本地分区的中间聚合以及一个用于合并所有分区结果的最终聚合函数。

 

如果通过并行可能会提高查询速度,PLINQ 则将源序列分区为可以同时运行的任务。 如果并行化查询不安全,PLINQ 则只会按顺序运行查询。 如果 PLINQ 可以在可能会较昂贵的并行算法或成本较低的顺序算法之间进行选择,它会默认选择顺序算法。 可以使用 WithExecutionMode 方法和 System.Linq.ParallelExecutionMode 枚举指示 PLINQ 选择并行算法。

 

默认情况下,PLINQ 使用主机计算机上的所有处理器。 可以使用 WithDegreeOfParallelism 方法指示 PLINQ 使用不超过指定数量的处理器。 

在查询要执行大量非受计算限制的工作(如文件 I/O)的情况下,最好指定比计算机上的内核数要大的并行度。


大多数情况下,无需为 PLINQ 查询指定合并选项。 不过,在某些情况下,通过测试和度量,可以发现查询在非默认模式下执行效果最佳。 这种做法的常见用途是,强制区块合并运算符流式传输结果,以提升用户界面的响应速度。

 

在 PLINQ 中,还可以使用 foreach 执行查询以及循环访问结果。 但是,foreach 本身不会并行运行,因此,它要求将所有并行任务的输出合并回该循环正在上面运行的线程中。 在 PLINQ 中,在必须保留查询结果的最终排序,以及以按串行方式处理结果时,例如当为每个元素调用 Console.WriteLine 时,则可以使用 foreach。 为了在无需顺序暂留以及可自行并行处理结果时更快地执行查询,请使用 ForAll 方法执行 PLINQ 查询。应尽量使用 ForAll 方法,让每个线程输出自己的结果。

 

ParallelEnumerable.Range强制使用范围划分,它不是Enumerable.Range(...).As-Parallel()的快捷写法,它通过激活范围划分策略改善了查询的性能。

ParallelEnumerable.Range (110000000)
                                  .Sum (i => Math.Sqrt (i))

 

默认情况下,前导任务和延续任务可能会在不同的线程上执行。如果希望它们在同一线程上执行则在调用ContinueWith方法时指定TaskContinuationOptions. ExecuteSynchronously选项。这种方式有助于降低细粒度延续的中间过程从而改善性能。

 

posted @ 2020-08-12 19:33  yetsen  阅读(103)  评论(0编辑  收藏  举报