C#使用“分块处理”和“并行处理”优化代码

模拟处理10万条List集合中的数据,

List<PeoMterModel> peoMterModels = new List<PeoMterModel>();
for (int i = 0; i < 100000; i++) 
{
    PeoMterModel peoMterModel=new PeoMterModel();
    peoMterModel.Id=Guid.Empty;
    peoMterModel.Name= i.ToString();
    peoMterModels.Add(peoMterModel);
}

设置每次处理20000条,判断需要多少个线程,用线程并行处理处理数据。每次处理2000条,则需要5个线程进行处理,计算需要设置多少个线程

int batchSize = 20000;
int numberOfTasks = (int)Math.Ceiling((double)peoMterModels.Count / batchSize);

用Task集合进行处理这些数据

var tasks = new List<Task>();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < numberOfTasks; i++)
{
    int start = i * batchSize;
    int end = Math.Min(start + batchSize, peoMterModels.Count);
    var batch = peoMterModels.GetRange(start, end - start);

    // 创建并启动任务
    var task = Task.Run(() => ProcessBatch(batch));
    tasks.Add(task);
}

// 等待所有任务完成
Task.WhenAll(tasks).Wait();
stopwatch.Stop();
TimeSpan elapsed = stopwatch.Elapsed;
Console.WriteLine($"Method execution time: {elapsed.TotalMilliseconds} ms");

void ProcessBatch(List<PeoMterModel> peoMterModels)
{
    for (int i = 0; i < peoMterModels.Count; i++) 
    {
        peoMterModels[i].Id = GetNew();
    }
}

Guid GetNew() 
{
    Guid guid = Guid.NewGuid();
    string aa = new Random().Next(100,20000).ToString();
    string bb = new Random().Next(156, 73751).ToString();
    string cc = new Random().Next(442, 58111).ToString();
    string dd = new Random().Next(3698, 14521).ToString();
    string ee = new Random().Next(1525, 69531).ToString();
    string f = new Random().Next(1455, 85231).ToString();
    double gjk= Convert.ToDouble((Convert.ToInt32(aa).ToString()))+ Convert.ToDouble((Convert.ToInt32(aa).ToString())) + Convert.ToDouble((Convert.ToInt32(bb).ToString())) + 
        Convert.ToDouble((Convert.ToInt32(cc).ToString())) + Convert.ToDouble((Convert.ToInt32(dd).ToString())) + Convert.ToDouble((Convert.ToInt32(ee).ToString()));
    double dadas = Convert.ToDouble((Convert.ToInt32(f).ToString())) / Convert.ToDouble((Convert.ToInt32(cc).ToString())) +
        Convert.ToDouble((Convert.ToInt32(aa).ToString())) + Convert.ToDouble((Convert.ToInt32(aa).ToString())) + Convert.ToDouble((Convert.ToInt32(bb).ToString())) +
        Convert.ToDouble((Convert.ToInt32(cc).ToString())) + Convert.ToDouble((Convert.ToInt32(dd).ToString())) + Convert.ToDouble((Convert.ToInt32(ee).ToString()))
        + Convert.ToDouble((Convert.ToInt32(gjk.ToString()).ToString()));

    string aa1 = new Random().Next(55, 75232).ToString();
    string bb1 = new Random().Next(4455, 18523).ToString();
    string cc1 = new Random().Next(155, 85244).ToString();
    string dd1 = new Random().Next(1875, 91523).ToString();
    string ee1 = new Random().Next(1455, 18523).ToString();
    string f1 = new Random().Next(1, 86001).ToString();

    double gjk2 = Convert.ToDouble((Convert.ToInt32(aa1).ToString())) + Convert.ToDouble((Convert.ToInt32(bb1).ToString())) + Convert.ToDouble((Convert.ToInt32(cc1).ToString())) +
        Convert.ToDouble((Convert.ToInt32(dd1).ToString())) + Convert.ToDouble((Convert.ToInt32(ee1).ToString())) + Convert.ToDouble((Convert.ToInt32(f1).ToString()));
    string sdad111 = (Convert.ToDouble((Convert.ToInt32(gjk).ToString())) + 
        Convert.ToDouble((Convert.ToInt32(dadas).ToString())) + Convert.ToDouble((Convert.ToInt32(gjk2).ToString()))).ToString();
    string sdad222 = "qwerwtqwtqfwqtywfqhwghqgwhwg"+$"{Convert.ToDouble((Convert.ToInt32(dadas).ToString()))+ Convert.ToDouble((Convert.ToInt32(gjk2).ToString()))}"+"fasdfsaf";

    PeoMterModel peoMterModel = new PeoMterModel();
    peoMterModel.GetModels();

    string json = JsonConvert.SerializeObject(peoMterModel);

    //Thread.Sleep(1000);
    //Thread.Sleep(100);
    //GC.Collect();
    return guid;
}

以上代码可以看到GetNew()方法有很多计算,还有序列化,模仿生产环境中的耗时操作;

执行完成后,发现执行时间为5276.2017ms

接下来直接测试,使用循环的方式进行处理,直接循环这10万条数据,依旧调用GetNew();这个耗时方式

Stopwatch stopwatch1 = new Stopwatch();
stopwatch1.Start();
//普通执行方法
for (int i = 0; i < peoMterModels.Count; i++)
{
    peoMterModels[i].Id = GetNew();
}
stopwatch1.Stop();
TimeSpan elapsed1 = stopwatch1.Elapsed;
Console.WriteLine($"Method execution time: {elapsed1.TotalMilliseconds} ms");

测试后发现需要15076.1498ms,相对于使用并行,速度增加了3倍

综上所述,建议使用“分块处理”和“并行处理”。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用OpenCVSharp分块的图像上并行计算Canny亚像素级别的匹配的C#代码示例: ```csharp using System; using System.Collections.Generic; using System.Threading.Tasks; using OpenCvSharp; namespace ParallelCanny { class Program { static void Main(string[] args) { // Load the image Mat image = Cv2.ImRead("test.jpg", ImreadModes.Grayscale); // Split the image into blocks List<Mat> blocks = SplitImage(image, 8); // Create a parallel loop to process each block Parallel.For(0, blocks.Count, i => { Mat block = blocks[i]; // Apply Canny edge detection to the block with sub-pixel accuracy Mat canny = new Mat(); Cv2.Canny(block, canny, 100, 200, 3, true); // Match template using normalized cross-correlation Mat result = new Mat(); Cv2.MatchTemplate(block, canny, result, TemplateMatchModes.CCoeffNormed); // Find the max value and location double minVal, maxVal; Point minLoc, maxLoc; Cv2.MinMaxLoc(result, out minVal, out maxVal, out minLoc, out maxLoc); // Output the result Console.WriteLine("Block {0}: Max value = {1}, Max location = ({2}, {3})", i, maxVal, maxLoc.X, maxLoc.Y); }); } static List<Mat> SplitImage(Mat image, int numBlocks) { List<Mat> blocks = new List<Mat>(); int blockWidth = image.Width / numBlocks; int blockHeight = image.Height / numBlocks; for (int i = 0; i < numBlocks; i++) { for (int j = 0; j < numBlocks; j++) { Rect roi = new Rect(j * blockWidth, i * blockHeight, blockWidth, blockHeight); Mat block = new Mat(image, roi); blocks.Add(block); } } return blocks; } } } ``` 在此示例中,我们首先加载图像,然后将其分成8个块。接下来,我们使用并行循环处理每个块,对每个块应用Canny边缘检测,并使用归一化的互相关匹配模板来查找亚像素级别的匹配。最后,我们输出每个块中最大值的位置和值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值