转载链接:.aspx .NET Framework 2.0中增加了一项新的诊断工具——“停表”StopWatch类,相比以前的计时系统,停表采用的是高精度计时方式,因此对性能测量更有帮助。为了试用 StopWatch类,我选择了一个经典的测试题目,VB中的IIf函数。IIf函数与C系列的?:三元运算符十分相似,可以在一行语句内完成判断和赋值 两项任务。但是,IIf是函数而不是运算符,其接受Object类型参数这一项已经够让人担忧的了。IIf到底有多慢呢?我们比较三个版本。首先是VB类 库中的Object版: Public Function IIf(Expression As Boolean, _ TruePart As Object, FalsePart As Object)As Object 第二个版本,是我编写的泛型版本的IIf,这个版本可以用于减少装箱拆箱过程带来的性能损失: Public Function IIf(Of T)(Expression As Boolean, _ TruePart As T, FalsePart As T)As T If Expression Then Return TruePart Else Return FalsePart End If End Function 第三个版本当然是直接使用If语句。我们已经很清楚哪个比较快,但是没有一个量的概念,通过高精度计时的测试,可以让我看到函数内联化带来的收益是否够多。下面是计时和测试的代码: Dim watch As New System.Diagnostics.Stopwatch
Dim j As Integer = 0 Dim f As Boolean = True
'Loop 10 times and get the average time For times As Integer = 1 To 10
watch.Start() For i As Integer = 0 To 1000000 j = Interaction.IIf(f, i, 5) Next watch.Stop()
Next
GC.Collect()
TextBox1.AppendText("Object IIf: " & watch.ElapsedMilliseconds / 10 & vbCrLf)
watch.Reset() For times As Integer = 1 To 10
watch.Start() For i As Integer = 0 To 1000000 j = IIf(f, i, 5) Next watch.Stop()
Next
GC.Collect()
TextBox1.AppendText("Generic IIf: " & watch.ElapsedMilliseconds / 10 & vbCrLf)
watch.Reset() For times As Integer = 1 To 10
watch.Start() For i As Integer = 0 To 1000000 If f Then j = i Else j = 5 Next watch.Stop()
Next
TextBox1.AppendText("Pure If: " & watch.ElapsedMilliseconds / 10 & vbCrLf) 我们看到StopWatch可以像真的停表一样开始,停止或继续,因此我们可以像在科学实验中计时一样使用它。而他的Elapsed属性可以提供各种单位的时间间隔。简单起见,我就用了毫秒。循环的次数不太多,取10次平均。最后的结果在我的机器上如下: Object IIf: 219.6 Generic IIf: 51.5 Pure If: 9.7 纯If仅9.7毫秒的间隔也能测试出来,足见StopWatch的精度比原来的计时手段高多了。而结果也表明,函数调用的代价已经相当可观,但还不 如装箱、拆箱带来的代价高。IIf当然是不要再用了,今后自己写函数时也应当注意,频繁调用的函数不能不考虑调用代价,内联化是不错的解决方案。 |
发布评论