用Tasks衡量内存分配的正确方法

时间:2019-04-23 11:29:17

标签: c# task

我需要减少用一小段代码创建/执行的任务的数量,因为可能存在大量的内存分配。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TaskMemoryUsage
{
    class Program
    {
        static void Main(string[] args)
        {
            int availableTaskCount = Environment.ProcessorCount;
            OriginalCalculationMethod();
            FirstCalculationMethod(availableTaskCount);
            SecondCalculationMethod(availableTaskCount);
            Console.ReadKey();
        }

        static TaskResult Calculate(int i)
        {
            //a lot of complicated calculations are made here
            return new TaskResult();
        }

        static List<TaskResult> OriginalCalculationMethod()
        {
            List<Task<TaskResult>> workersArray = new List<Task<TaskResult>>();
            long memStart = GC.GetTotalMemory(true);
            for (int i = 0; i < 10000; ++i)
            {
                workersArray.Add(
                        Task.Factory.StartNew(
                            new Func<TaskResult>(() => Calculate(i))
                    ));
            }
            Task.WaitAll(workersArray.ToArray());

            long memEnd = GC.GetTotalMemory(true);
            Console.WriteLine($"DIFFERENCE = {memEnd - memStart}");

            return workersArray.Select(s => s.Result).ToList(); 
        }

        static List<TaskResult> FirstCalculationMethod(int availableTaskCount)
        {           
            long memStart = GC.GetTotalMemory(true);
            using (SemaphoreSlim semaphore = new SemaphoreSlim(availableTaskCount))
            {
                List<Task<TaskResult>> tasks = new List<Task<TaskResult>>();
                for (int i = 0; i < 10000; ++i)
                {
                    Task<TaskResult> task = Task.Factory.StartNew(() =>
                    {
                        try
                        {
                            semaphore.Wait();
                            return Calculate(i);
                        }
                        finally
                        {
                            semaphore.Release();
                        }
                    });
                    tasks.Add(task);
                }
                Task.WaitAll(tasks.ToArray());
                long memEnd = GC.GetTotalMemory(true);
                Console.WriteLine($"DIFFERENCE = {memEnd - memStart}");

                return tasks.Select(s => s.Result).ToList();
            }
        }


        static List<TaskResult> SecondCalculationMethod(int availableTaskCount)
        {
            List<Task<TaskResult>> workersArray = new List<Task<TaskResult>>();
            List<TaskResult> tasksResults = new List<TaskResult>();
            long memStart = GC.GetTotalMemory(true);
            for (int i = 0; i < 10000; ++i)
            {
                workersArray.Add(Task.Factory.StartNew(new Func<TaskResult>(() => Calculate(i))
                                                                ));
                if (workersArray.Count >= availableTaskCount)
                {
                    Task.WaitAll(workersArray.ToArray());
                    tasksResults.AddRange(workersArray.Select(t => t.Result));
                    workersArray.Clear();
                }
            }

            Task.WaitAll(workersArray.ToArray());
            long memEnd = GC.GetTotalMemory(true);
            Console.WriteLine($"DIFFERENCE = {memEnd - memStart}");

            return tasksResults;
        }
    }

    class TaskResult
    {
        public double[] calculationResult;
    }
}

我在上一个解决方案中获得了最佳结果,但是我不确定自己是否能正确测量它,所以我想问一下我是否针对此问题正确地测量了内存分配,我的解决方案是否正确,或者是否有更好的解决方案立即消耗的内存分配。

0 个答案:

没有答案