我的代码如下:
Accept(IVisitor)
数组中的每个元素都实现UrlFetch
接口,该接口具有headers
方法。只有标准的访客模式。
在测量性能的同时,我得出的结论是,接口调用太慢了,在这段代码中,性能至关重要。根据您的经验,消除任何虚拟或接口呼叫的最佳选择是什么?检查具体类型的if语句?带有switch / case的每个元素的枚举(在这种情况下,代码的结构是不需要强制转换的)?还有别的吗?
P.S。我无法对数组中的项进行排序。订单很重要。因此,我不能按具体类型对它们进行排序以帮助进行分支预测。
答案 0 :(得分:2)
我创建了以下程序。在我的笔记本电脑上,循环在8ms内运行了一百万次(这是Release版本,Debug是11ms左右)。这大约是0.000008ms来进行虚拟调度并增加一个int。究竟你有多快需要它?我怀疑你的表现测试或我的表现都出了问题。如果我的,我有兴趣听取改进建议。
通常,如果此级别的性能不够好,那么使用C#本身可能是一个问题。它的垃圾收集器有一个习惯,就是在循环中间冻结线程。如果在循环迭代中0.000008ms确实是一个问题,我怀疑汇编语言或C将是一个更好的选择。
a /home/store//.snapshot/hourly.0/d2/dd/d5d/f83-1 58K
答案 1 :(得分:1)
你这里没有一个虚拟电话,你有两个,但你只需要一个。首先,您的阵列可能通过IItem进行虚拟呼叫 - 但如果它们都是相同的类型,并且您知道类型(并且它已被密封),则不需要进行虚拟呼叫。
然后在访问对象中,您需要执行访问者想要执行的任何操作。这可能还涉及虚拟呼叫。
使用类型化的IVisitor可能会做得更好:
interface IItem<TVisitor> : IItem
where TVisitor : IVisitor
{
void Accept(TVisitor visitor);
}
// Then
SpecialVisitor visitor = ImplementsSpecialVisitor();
foreach(var item in arrayOfSpecialItems){
item.Accept<SpecialVisitor>(visitor);
}