我有一个for循环创建了4个任务,每个任务都打印出它的循环索引 - 简单的程序来测试性能
我有一个外部循环,运行上述循环1000次(迭代) 我想检查TASK和线程的性能
(1)测试1:我认为这只会创建TASK(而非线程),但我发现它使用了TPL
tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));
(2)我用TaskCreationOptions.LongRunning重写了如下
tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp), TaskCreationOptions.LongRunning);
(3)然后我尝试使用与上面相同的代码测试THREADs而不是任务,但现在使用“new Thread”而不是工厂
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();
}
时间结果显示最佳性能是(2),然后是(3),然后是(1)
请能解释一下性能结果的原因,并解释上面哪一个真正只是一个任务(一个O.S.进程)和哪些正在使用线程?
我尝试使用了探查器,但只能访问Visual Studio 2010 Professional,并且看起来探查器只带有permium或终极版本。
答案 0 :(得分:1)
Task.Factory.StartNew(
使用ThreadPool中的线程
LongRunning
意味着,每个任务都应该创建自己的线程,因为它长时间运行而且我们不想让游泳池干燥
最后一个选项只是创建线程。
您是否检查了每个案例的内存使用情况?
答案 1 :(得分:0)
在这种情况下,使用Console.WriteLine
作为测试性能的操作毫无意义。在所有情况下,每次迭代都会从池中生成或重用新线程。这是一件相对昂贵的事情。这意味着,只要您的操作是微不足道的,线程产生或重用成本的开销将总是会影响您的性能测试。
如果你的线程中有一个真正的,非平凡的操作,你的案例之间的产生成本差异将不再重要。除此之外,当使用Task
时,如果创建新线程或重用池中的一个线程,使用Tasks
时几乎无法控制,这总是一件好事。我的建议是,当您需要在后台处理某些内容并将头痛的东西留给框架时,请使用TPL
。
我希望这是可以理解的。
而且,出于实际目的,如果您有大量要计算的内容并希望使用多核cpu,您还可以查看Parallel.Foreach或Parallel.Foreach
提供的其他内容。
编辑:{{1}},喜欢的人会自行决定是否以及何时产生新线程。使用此方法将为您提供最大的灵活性,因为运行时将决定您,具体取决于处理器数量,列表大小等,如果它有意义创建新线程或者开销会增加更多。