并行中的分区Partitioner
生活随笔
收集整理的這篇文章主要介紹了
并行中的分区Partitioner
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本篇介紹在C#中,把一個大集合,或大數組分成若干個區來執行。Demo中是把一組字符串放在list中,然后并行生成MD5串,返回回來。
using?System; using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; using System.Linq; using System.Collections.Concurrent;public class Program {public static async Task Main(string[] args){await PartitionerDemoAsync();}public static string ToMD5Hash(string str){if (string.IsNullOrEmpty(str)){return null;}var bytes = Encoding.ASCII.GetBytes(str);if (bytes == null || bytes.Length == 0){return null;}using (var md5 = MD5.Create()){return string.Join("", md5.ComputeHash(bytes).Select(x => x.ToString("X2")));}}static async Task<List<string>> PartitionA(IEnumerator<string> partition){using (partition){var list = new List<string>();while (partition.MoveNext()){list.Add(ToMD5Hash(partition.Current));}Console.WriteLine($"======={list.Count}========");return await Task.FromResult(list);}}static async Task PartitionerDemoAsync(){while (true){Console.ReadLine();var source = new List<string>();for (var i = 0; i < 80000; i++){source.Add($"{i}{DateTime.Now.ToString("yyyyMMddHHmmssfffffff")}");}var list = Partitioner.Create(source).GetPartitions(12).AsParallel().Select(PartitionA);var count = 0;foreach (var item in list){count++;foreach (var t in await item){Console.WriteLine($"---{count}---{t}-----");}}}} }我電腦是配置是8核。
這是把區分成8個后,80000個元素,三次分配的結果。元素越多,相對分配置比較均勻。
當把分區設置成12時,會發現三次分區中,總是有四個分不到的,說明.GetPartitions(12)會查看本機的cpu核心數,把分區的上限限制在核心數上,可以少于等于這個值,可以理解,多了沒有cpu去運算,也沒有意義了。
最后,用Benchmark跑一下用分區的和不分區的狀態下生成80000個md5結果:
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks;namespace Demo01 {public class ParallelDemo2 : IDemo{public void Run(){BenchmarkRunner.Run<TestParallelDemo2>();}}public class TestParallelDemo2{[Benchmark]public void DemoAsync(){var list = new List<string>();for (var i = 0; i < 80000; i++){list.Add(ToMD5Hash($"{i}{DateTime.Now.ToString("yyyyMMddHHmmssfffffff")}"));}foreach (var item in list){// Console.WriteLine($"-----{item}-----");}}[Benchmark]public async Task PartitionerDemoAsync(){var source = new List<string>();for (var i = 0; i < 80000; i++){source.Add($"{i}{DateTime.Now.ToString("yyyyMMddHHmmssfffffff")}");}var list = Partitioner.Create(source).GetPartitions(12).AsParallel().Select(PartitionA);foreach (var item in list){foreach (var t in await item){// Console.WriteLine($"-----{t}-----");}}}string ToMD5Hash(string str){if (string.IsNullOrEmpty(str)){return null;}var bytes = Encoding.ASCII.GetBytes(str);if (bytes == null || bytes.Length == 0){return null;}using (var md5 = MD5.Create()){return string.Join("", md5.ComputeHash(bytes).Select(x => x.ToString("X2")));}}async Task<List<string>> PartitionA(IEnumerator<string> partition){using (partition){var list = new List<string>();while (partition.MoveNext()){list.Add(ToMD5Hash(partition.Current));}//Console.WriteLine($"======={list.Count}========");return await Task.FromResult(list);}}} }分區明顯要優于普通方式,數據越多,優勢越明顯。
總結
以上是生活随笔為你收集整理的并行中的分区Partitioner的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 代码生成二维码方法及代码示例(QR
- 下一篇: Ant Design Blazor 组件