Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net DirectCast对性能和后期/早期绑定有什么影响?_Vb.net_Performance_Directcast - Fatal编程技术网

Vb.net DirectCast对性能和后期/早期绑定有什么影响?

Vb.net DirectCast对性能和后期/早期绑定有什么影响?,vb.net,performance,directcast,Vb.net,Performance,Directcast,我一直认为DirectCast()相当便宜,性能和内存都很好,并且基本上把它看作是帮助我使用IntelliSense的一种方式,例如在事件处理程序中: Public Sub myObject_EventHandler(sender As Object, e As System.EventArgs) 'Explicit casting with DirectCast Dim myObject As myClass = DirectCast(sender, myClass)

我一直认为
DirectCast()
相当便宜,性能和内存都很好,并且基本上把它看作是帮助我使用IntelliSense的一种方式,例如在事件处理程序中:

Public Sub myObject_EventHandler(sender As Object, e As System.EventArgs)
    'Explicit casting with DirectCast
    Dim myObject As myClass = DirectCast(sender, myClass)

    myObject.MyProperty = "myValue"
End Sub
显然,作为一名开发人员,我认为这对我来说更好,但对编译后的代码和结果性能也更好,因为它启用了“早期绑定”,而不是

Public Sub myObject_EventHandler(sender As Object, e As System.EventArgs)
    'No casting at all (late binding)
    myObject.MyProperty = "myValue"
End Sub
。。。它也可以编译和运行,但是如果我没有弄错的话,它会使用“后期绑定”。i、 e.假设
sender
实际上是
myClass
对象

在性能、后期/早期绑定或其他方面,上面的第一个代码段与下面的代码段有什么区别:

Public Sub myObject_EventHandler(sender As Object, e As System.EventArgs)
    'Implicit casting via variable declaration
    Dim myObject As myClass = sender

    myObject.MyProperty = "myValue"
End Sub

显式的
DirectCast()
调用是有用的还是有害的,还是在编译器优化了代码后没有什么区别?

我建议在for循环中运行延迟绑定和直接强制转换大约100000次,看看两者之间是否有时间差


为两个循环创建秒表并打印结果。如果有什么不同,请告诉我们。100000次可能太少,实际上可能会让它运行更长时间

TL;灾难恢复版本: 使用
DirectCast()
而不是后期绑定或反射,以获得更好的运行时性能

这个问题对我来说很有趣。我几乎定期为我编写的每个应用程序使用
DirectCast()
。我一直使用它,因为它使IntelliSense工作,如果我不严格使用
选项,那么编译时就会出错。如果我急于测试一个设计概念,或者急于为一个一次性问题找到一个快速而肮脏的解决方案,我会时不时地使用
选项Strict Off
。在使用它的过程中,我从来没有考虑过性能影响,因为我写的东西从来都不需要关心运行时的性能

思考这个问题让我有点好奇,所以我决定自己测试一下,看看其中的区别。我在VisualStudio中创建了一个新的控制台应用程序并开始工作。下面是应用程序的完整源代码。如果您想亲自查看结果,您应该能够直接复制/粘贴:

选项严格关闭
选项显式打开
导入系统。诊断
输入系统。反射
导入System.IO
导入系统文本
模块1
常量loopCntr作为Int32=1000000
常量迭代Cntr作为Int32=5
Const resultPath As String=“C:\StackOverflow\DirectCastResults.txt”
副标题()
Dim objDirectCast作为新的MyObject(“objDirectCast”)
作为新MyObject的Dim objImplicitCasting(“objImplicitCasting”)
将对象绑定为新的MyObject(“对象绑定”)
作为新MyObject的Dim objReflection(“objReflection”)
Dim objInvokeMember作为新的MyObject(“objInvokeMember”)
作为新的StringBuilder运行:sbeapped.Append(“Running”).Append(iterationCntr.Append(“iterations for”).Append(loopCntr.AppendLine(“循环”)
将sbAverage作为新的StringBuilder进行调整:sbAverage.AppendLine()
AddHandler objDirectCast.ValueSet,SetObjectDirectCast的地址
AddHandler objImplicitCasting.ValueSet,SetObjectImplictCasting的地址
AddHandler objLateBound.ValueSet,SetObjectLateBound的地址
AddHandler objReflection.ValueSet,SetObjectReflection的地址
AddHandler objInvokeMember.ValueSet,SetObjectInvokeMember的地址
对于{objDirectCast、objimplicitcast、objLateBound、objReflection、objInvokeMember}中作为MyObject的每个MyObject
Dim resultlist作为新列表(时间跨度)
sbappeased.AppendLine().Append(“所用时间(秒)”).Append(myObj.Name).Append(“是:”)
对于i=1到iterationCntr
新秒表
stpWatch.Start()
对于_i=0到loopCntr
myObj.SetValue(_i)
下一个
停下来
sbappead.Append(stpWatch.appead.TotalSeconds.ToString()).Append(“,”)
添加(stpWatch.appeased)
Console.WriteLine(myObj.Name&“已完成”)
下一个
当长度=0升时变暗总刻度
resultlist.ForEach(Sub(x为TimeSpan)totalTicks+=x.Ticks)
Dim averageTimeSpan作为新的TimeSpan(totalTicks/CLng(resultlist.Count))
sbAverage.Append(“平均运行时间”).Append(myObj.Name).Append(“is:”).AppendLine(averageTimeSpan.ToString)
下一个
将strWriter用作新的StreamWriter(File.Open(resultPath、FileMode.Create、FileAccess.Write))
strWriter.WriteLine(sbappeased.ToString)
strWriter.WriteLine(sbAverage.ToString)
终端使用
端接头
子集合ObjectDirectCast(发送方作为对象,newValue作为Int32)
作为MyObject的Dim MyObject=DirectCast(发送方,MyObject)
myObj.MyProperty=newValue
端接头
子集合ObjectImplictCasting(发送方作为对象,新值作为Int32)
将MyObject设置为MyObject=发送方
myObj.MyProperty=newValue
端接头
Sub-SetObjectLateBound(发送方作为对象,newValue作为Int32)
sender.MyProperty=newValue
端接头
Sub-SetObjectReflection(发送方作为对象,newValue作为Int32)
Dim pi As PropertyInfo=sender.GetType().GetProperty(“MyProperty”,BindingFlags.Public+BindingFlags.Instance)
pi.SetValue(发送方、newValue、Nothing)
端接头
子SetObjectInvokeMember(发送方作为对象,新值作为Int32)
sender.GetType().InvokeMember(“MyProperty”,BindingFlags.Instance+BindingFlags.Public+BindingFlags.SetProperty,Type.DefaultBinder,sender,{newValue})
端接头
端模块
公共类MyObject
Private _MyProperty作为Int32=0
公共事件值集(发送方作为对象,新值作为Int32)
公共财产