关于一个代码设计问题,我只是碰巧遇到了这样的情况。比如说,我有一个"模板"方法,它调用一些可能会"改变"的函数。一个直观的设计是遵循"模板设计模式"。将改变函数定义为需要在子类中重载的"虚拟"函数。或者,我可以只使用委托函数而无需使用"虚拟"。将委托函数注入以便也可以进行自定义。
最初,我认为第二种"委托"方式比"虚拟"方式更快,但一些编码片段证明这是不正确的。
在下面的代码中,第一个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);
}
}
}