它只是发生在我的一个代码设计问题上。比如说,我有一个“模板”方法,它调用一些可能“改变”的函数。一个直观的设计是遵循“模板设计模式”。将更改函数定义为要在子类中覆盖的“虚拟”函数。或者,我可以只使用没有“虚拟”的委托函数。委托函数被注入,因此它们也可以被定制。
最初,我认为第二种“委托”方式会比“虚拟”方式更快,但一些代码片段证明它是不正确的。
在下面的代码中,第一个 DoSomething 方法遵循“模板模式”。它调用虚拟方法 IsTokenChar。第二种 DoSomthing 方法不依赖于虚函数。相反,它有一个传入委托。在我的电脑中,第一个 DoSomthing 总是比第二个快。结果就像 1645:1780。
“虚拟调用”是动态绑定,应该比直接委托调用更耗时,对吧?但结果表明并非如此。
有人可以解释一下吗?
using System;
using System.Diagnostics;
class Foo
{
public virtual bool IsTokenChar(string word)
{
return String.IsNullOrEmpty(word);
}
// this is a template method
public int DoSomething(string word)
{
int trueCount = 0;
for (int i = 0; i < repeat; ++i)
{
if (IsTokenChar(word))
{
++trueCount;
}
}
return trueCount;
}
public int DoSomething(Predicate<string> predicator, string word)
{
int trueCount = 0;
for (int i = 0; i < repeat; ++i)
{
if (predicator(word))
{
++trueCount;
}
}
return trueCount;
}
private int repeat = 200000000;
}
class Program
{
static void Main(string[] args)
{
Foo f = new Foo();
{
Stopwatch sw = Stopwatch.StartNew();
f.DoSomething(null);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
{
Stopwatch sw = Stopwatch.StartNew();
f.DoSomething(str => String.IsNullOrEmpty(str), null);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
}