简体   繁体   中英

.NET and Task Parallel Library

I have a for loop that creates 4 tasks and each task prints its loop index - simple program to test performance

I have an outside loop that run the above loop 1000 times (iterations) I wanted to check the performance of TASKs and Threads

(1) Test 1:I thought this would create TASKs (not threads) only but I found it uses TPL

tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));

(2) I rewrote with the TaskCreationOptions.LongRunning as follows

tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp), TaskCreationOptions.LongRunning);

(3) Then I tried to test THREADs not task using the same code as above but now using "new Thread" instead of factory

for (int i = 0; i < 4; i++)
{
    var tmp = i;
    tasks[i] = new Thread(new ThreadStart(() => Console.WriteLine(tmp)));
    tasks[i].Start();
    tasks[i].Join();
}

The timing results showed the best performance is (2), then (3), then (1)

Please can one explain the reasonsof the performance results, and explain which one of the above truly just a task (an OS Process) and which are using threads?

I tried to use the profiler, but only have access to Visual Studio 2010 Professional and it appears the profiler comes only with the permium or ultimate version.

Task.Factory.StartNew(

Uses threads from the ThreadPool

LongRunning means, each task should create it's own thread, because it's long running and we don't want to dry the pool

The last option just create threads.

Did you check the memory usage for each case?

Using Console.WriteLine as the action for testing perfomance in this case is pointless. Under the hood in all of your cases a new thread is spawn or reused from the pool for each iteration. This is a relatively costly thing to do. That means, as long as your operation is trivial, the overhead of the thread spawn or reuse costs will always compromise your performance test a lot.

And if your having a real, non-trivial operation going on in your threads, the spawn cost differences between your cases won´t matter anymore. In addition to that, you have very little control when using Task when and if a new thread is created or one from the pool is reused, which is always a good thing btw. My advice is, use Tasks when you have the need to process something in the background and leave the headache stuff to the framework.

I hope this is understandable.

And, for practical purposes, if you have big lists of things to compute and want to make use of multicore cpus you could also take a look at Parallel.Foreach or other things provided by the TPL .

Edit: Parallel.Foreach and the likes will decide for themselves if and when to spawn new threads. Using this methods will give you a maximum of flexibility because the runtime will decide for you, depending on the processor count, size of the list, etc. if its making sense to create new threads or if the overhead would be bigger as the gain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM