我还没有看到这种效果——我当然从来没有遇到过瓶颈.
下面是一个非常粗略且现成的基准测试,它显示(无论如何在我的盒子上)代理实际上比接口多faster个:
using System;
using System.Diagnostics;
interface IFoo
{
int Foo(int x);
}
class Program : IFoo
{
const int Iterations = 1000000000;
public int Foo(int x)
{
return x * 3;
}
static void Main(string[] args)
{
int x = 3;
IFoo ifoo = new Program();
Func<int, int> del = ifoo.Foo;
// Make sure everything's JITted:
ifoo.Foo(3);
del(3);
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
{
x = ifoo.Foo(x);
}
sw.Stop();
Console.WriteLine("Interface: {0}", sw.ElapsedMilliseconds);
x = 3;
sw = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
{
x = del(x);
}
sw.Stop();
Console.WriteLine("Delegate: {0}", sw.ElapsedMilliseconds);
}
}
结果(.NET 3.5;.NET 4.0b2大致相同):
Interface: 5068
Delegate: 4404
现在我并不特别相信这意味着代理比接口快really个...但这让我相当确信,它们并没有慢一个数量级.此外,在委托/接口方法中,这几乎不起任何作用.显然,随着每次调用所做的工作越来越多,调用成本的影响将越来越小.
需要注意的一点是,在只使用单个接口实例的情况下,不要多次创建新委托.这could会引发一个问题,因为它会引发垃圾收集等.如果在循环中使用实例方法作为委托,您会发现在循环外声明委托变量、创建单个委托实例并重用它更有效.例如:
Func<int, int> del = myInstance.MyMethod;
for (int i = 0; i < 100000; i++)
{
MethodTakingFunc(del);
}
比以下各项更高效:
for (int i = 0; i < 100000; i++)
{
MethodTakingFunc(myInstance.MyMethod);
}
这会不会就是你看到的问题?