当我创建一个通过Activator.CreateInstance
或new
关键字实现接口的类的对象时,执行速度明显不同。我首先使用的创建类型对于程序执行的其余部分来说是更快的。我写了以下“性能测试”:
static private void SpeedTest(IPlugin plugin)
{
Console.Write("SpeedTest of \"" + plugin.Name + "\": ");
Stopwatch sw = new Stopwatch();
int workingNumber = 0;
sw.Start();
for (int i = 0; i < 2147483647; i++)
{
plugin.Add(ref workingNumber);
plugin.DSub(ref workingNumber);
plugin.Add(ref workingNumber);
}
sw.Stop();
Console.WriteLine(sw.Elapsed.ToString());
}
我通过以下方式加载实现IPlugin的类的实例:
static void Main(string[] args)
{
IPlugin pluginInstance = null;
IPlugin localInstance = new LocalPlugin();
Assembly plugin = Assembly.LoadFile("Path\\Plugin.dll");
Type pluginInterface = typeof(IPlugin);
foreach (Type type in plugin.GetTypes())
if (pluginInterface.IsAssignableFrom(type))
pluginInstance = (IPlugin)Activator.CreateInstance(type);
SpeedTest(localInstance);
SpeedTest(pluginInstance);
SpeedTest(localInstance);
SpeedTest(pluginInstance);
}
IPlugin看起来像:
public interface IPlugin
{
string Name { get; }
void Add(ref int number);
void DSub(ref int number);
}
“本地”插件(以及来自Plugin.dll的远程插件,除了它有一个public
- 修饰符并且返回“远程”而不是“本地”)时看起来像:< / p>
class LocalPlugin : IPlugin
{
public string Name
{
get { return "Local"; }
}
public void Add(ref int number)
{
number++;
}
public void DSub(ref int number)
{
number -= 2;
}
}
以下是两个项目供您下载:ZIP-File with example projects
您需要在PluginHost
- 项目之前编译Plugin
- 项目。
现在这个测试块的程序输出
SpeedTest(pluginInstance);
SpeedTest(localInstance);
SpeedTest(pluginInstance);
SpeedTest(localInstance);
是:
SpeedTest of "Plugin": 00:00:25.9785649
SpeedTest of "Local": 00:00:38.8875138
SpeedTest of "Plugin": 00:00:25.8757588
SpeedTest of "Local": 00:00:38.5222134
如果我将第一行移动到最后一个位置:
SpeedTest(localInstance);
SpeedTest(pluginInstance);
SpeedTest(localInstance);
SpeedTest(pluginInstance);
我得到以下输出:
SpeedTest of "Local": 00:00:26.1881051
SpeedTest of "Plugin": 00:00:38.9942815
SpeedTest of "Local": 00:00:25.9634257
SpeedTest of "Plugin": 00:00:38.6881451
结论:我首先使用的实例化类型比第二个快。此行为是方法独立的。
问题:
的问候,
的Matthias
答案 0 :(得分:0)
埋在以下文章中的原因是:
A curious subtlety about how CLR does interface dispatch on array types
感兴趣的具体文字如下:
我们的接口调度逻辑有一个重要的优化,其中FOR EACH CALL SITE,它显式地检查一个特定目标,如果失败,则执行较慢的哈希表查找,如果该查找失败,则回退到昂贵的查找。因此,对于往往到达一个目的地的呼叫站点而言,它非常快,并且呼叫到达许多目标的站点,你会变得很好,但性能却不是很好。
根据出现的第一个对象的具体类型初始化呼叫站点优化。
您应该能够通过将测试中的IPlugin
接口替换为PluginBase
类来产生公平的比较。