这里可能要解释一下什么是结构化:一切有条不紊、充满合理逻辑和准则的。一个定律
在早期使用汇编编程时,为了更加契合计算机运行的实际状况,控制流分为“顺序执行”和“跳转”,这里的跳转也就是著名的--goto,无条件跳转可能会使得代码运行杂乱无章,不可预测。Dijkstra著名的goto有害论的中翻地址:https://www.emon100.com/goto-translation/
注意:这一部分提供的所有代码都可以在 LINQPad 中试验。
使用类也能获得相同的结果,但是性能会有所下降。因为类是引用类型,在堆中分配,只后还有垃圾回收。输出,成功的找到了刚刚故意引入拼写错误的两个单词
这个区别对LINQ而言影响并不是很大,但对于PLNQ而言,基于栈的内存分配相当有利。因为每个线程都有自己的独立栈,可以高度并行化,而堆内存会使多个线程竞争同一个堆(竞态),它是由单一的内存管理器和垃圾回收器管理的。
注意,PLINQ 切分的任务是由线程池线程执行,线程池的线程并不是取之不尽用之不竭的,具体在下一part讲。
在一个 PLINQ 中,仅能调用WithDegreeOfParallelism一次。如果你需要再次调用它,必须再次调用AsParallel()强制进行查询的合并和重新分区取消
PLINQ 不会直接中止线程,因为这么做是危险的。在取消时,它会等待所有工作线程处理完当前的元素,然后才抛出OperationCanceledException 结束查询。聚合
接下来我们会大量出现这种模式,这也是受益PFX底层设计保持高度一致。
并不一定是相邻分配,也可能采用条纹式(striping)策略
使用ParallelEnumerable 中返回IParallelQuery的方法不需要再调用AsParallel(这里有防呆设计)
第二个参数一定要传true,表示开启负载均衡,使用动态分区。否则用的是静态索引做范围分区。到底是什么分区,用的时候还是建议自己去看一下源码,这一块策略较多,讲不完。
结果的整理和枚举开销相对并不大,只有当序列非常大且执行迅速时才能体现,例如图片处理,整理几百万个像素到输出序列可能形成性能瓶颈。更好的方法是把像素直接写入数组或非托管的内存块,然后使用Parallel类或Task来管理多线程也可以直接使用ForAll来绕过结果整理。.NET现代化并行编程系统的双子星即将登场。。。
这些API在你传递远超于处理器核心数量的任务时仍然能够高效功能,他们会对任务进行分区,再对其分配底层的Task,而非对每一个任务创建独立的TaskInvoke
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |