我的电脑有一个双核CPU,我想知道 - 如果我开始在两个线程中处理,是否可以将.NET反射时间减少两个。
通过“处理”,我的意思如下:
1.装载组件 2.忘记所有类型(.GetTypes()) 3.处理这些类型 4.为这些方法挑选这些类型 等
如果是的话 - 什么是最好的(表现明智的)策略:
答案 0 :(得分:3)
要记住以下几点:
启动一个新线程是很昂贵的,所以如果任务是短暂的,那么开销可能会过高。通过使用线程池而不是启动自己的线程,线程池将确保尽可能地重用线程。但是,在当前线程池实现中,在短时间内启动大量任务不会产生最佳结果。
由于您的特定任务涉及一些I / O,这可能是操作中最昂贵的部分。分离几个线程以等待I / O可能无法产生更好的性能。在测量它之前你无法确定。
如果您将数据存储在共享存储库中或输出到文件/屏幕,则必须同步。这显然会降低并发性。
答案 1 :(得分:1)
在单独的线程中加载和处理每个程序集更快。但只是快一点。例如,通过缓存MethodInfos可以获得更好的成功。
我会质疑是否需要这样的优化。
结果:
warm up single threaded Time Elapsed 465 ms multi threaded Time Elapsed 173 ms single threaded Time Elapsed 456 ms
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Diagnostics;
namespace ConsoleApplication12 {
class Program {
static void TimeAction(string description, Action func) {
var watch = new Stopwatch();
watch.Start();
func();
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
static void Main(string[] args) {
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
// warm up
TimeAction("warm up single threaded", () =>
{
foreach (var assembly in assemblies) {
assembly.GetTypes().Select(type => type.GetMethods()).ToArray();
}
});
List<Thread> threads = new List<Thread>();
TimeAction("multi threaded", () => {
foreach (var assembly in assemblies) {
Thread t = new Thread(new ThreadStart( () =>
assembly.GetTypes().Select(type => type.GetMethods()).ToArray()
));
t.Start();
threads.Add(t);
}
foreach (var thread in threads) {
thread.Join();
}
});
TimeAction("single threaded", () =>
{
foreach (var assembly in assemblies) {
assembly.GetTypes().Select(type => type.GetMethods()).ToArray();
}
});
Console.ReadKey();
}
}
}
答案 2 :(得分:1)
除非你正在处理绝对庞大的库,否则根据我的经验,反射加载并不是一件非常慢的事情。这可能会浪费你的时间。
尽管如此,请查看ThreadPool.QueueUserWorkItem,使这些内容变得简单。
foreach (Assembly a in "folder/something") {
ThreadPool.QueueUserWorkItem((object assem) => {
// do work
}, a);
}