任何类转换成父类使用,是否影响效率。

indusl 2014-03-26 11:29:06
比如 类C 转成 祖父类A,转换过来是否有额外的开销而影响效率?

如果 类C 转成 根类Object呢?
...全文
869 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
indusl 2014-03-28
  • 打赏
  • 举报
回复
引用 21 楼 sbwwkmyd 的回复:
[quote=引用 20 楼 indusl 的回复:]求高人解答直接用 this.接口方法() 和 ((接口)this).接口方法() 之间到底有什么性能上区别? 后者的用法有什么优点?
降低了运行效率,没有什么优点。有时候不得不这么写,比如实现了两个接口,方法签名都一样。[/quote] .net 框架里的类库有大量这样的用法,都是先转成接口类再调用接口方法。
likevs 2014-03-28
  • 打赏
  • 举报
回复
引用 21 楼 sbwwkmyd 的回复:
[quote=引用 20 楼 indusl 的回复:]求高人解答直接用 this.接口方法() 和 ((接口)this).接口方法() 之间到底有什么性能上区别? 后者的用法有什么优点?
降低了运行效率,没有什么优点。有时候不得不这么写,比如实现了两个接口,方法签名都一样。[/quote] 同意。 实际上,直接this.接口方法();编译器有没有隐式执行((接口)this)这一步操作,还有得研究 微软隐藏了太多东东,比如,自定义类时,表面上没有继承任何基类,结果,编译器自动加上object public ClassA : object {}
wylp_19 2014-03-27
  • 打赏
  • 举报
回复
这样很危险,如果使用了子类才有的方法,就会报错
showjim 2014-03-27
  • 打赏
  • 举报
回复
引用 14 楼 indusl 的回复:
所以,比如上面的String定义,如果转换成Object无开销,那么它就不必实现泛型接口了
知道你说的什么了。IEnumerable<char>不用说避免了object与char的装拆箱操作。IComparable<string>你看看源码就明白了,比如
public int CompareTo(object value)
{
    if (value == null)
    {
        return 1;
    }
    if (!(value is string))
    {
        throw new ArgumentException(Environment.GetResourceString("Arg_MustBeString"));
    }
    return Compare(this, (string) value, StringComparison.CurrentCulture);
}

public int CompareTo(string strB)
{
    if (strB == null)
    {
        return 1;
    }
    return CultureInfo.CurrentCulture.CompareInfo.Compare(this, strB, CompareOptions.None);
}
虽然没有IEquatable,如果有的话和IComparable是一样的问题。
showjim 2014-03-27
  • 打赏
  • 举报
回复
引用 12 楼 indusl 的回复:
没太明白你的意思。 直接用this.接口方法() 和 ((接口)this).接口方法() 之间到底有什么性能上区别?
this.XXX()目标地址是直接确定的,接口.XXX()目标地址是不确定的,需要JIT为每个类型生成一个查询表。
引用 13 楼 indusl 的回复:
从基础类型的定义来看,他们都没有显示从Object类派生,比如 public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string> 所以,我感觉任何类(就是说说引用类型,值类型就不讨论了)转换成Object亦需要一定的系统开销,当然可能比值类型的装箱拆箱小一点。
所有class都是继承自object,不需要显示定义。 任何class类型转换成object的开销仅仅是绑定类型(一个赋值操作而已),如果是及时使用的话就会被内联优化。
引用 14 楼 indusl 的回复:
所以,比如上面的String定义,如果转换成Object无开销,那么它就不必实现泛型接口了
这句话没看明白你要说什么,转换成object与泛型接口有什么关系?
indusl 2014-03-27
  • 打赏
  • 举报
回复
引用 11 楼 sbwwkmyd 的回复:
还有一点区别,普通方法是可能被内联优化的(这个效率差别就比较大了),而虚方法是不能被内联优化的。
所以,比如上面的String定义,如果转换成Object无开销,那么它就不必实现泛型接口了
indusl 2014-03-27
  • 打赏
  • 举报
回复
引用 11 楼 sbwwkmyd 的回复:
还有一点区别,普通方法是可能被内联优化的(这个效率差别就比较大了),而虚方法是不能被内联优化的。
从基础类型的定义来看,他们都没有显示从Object类派生,比如 public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string> 所以,我感觉任何类(就是说说引用类型,值类型就不讨论了)转换成Object亦需要一定的系统开销,当然可能比值类型的装箱拆箱小一点。
indusl 2014-03-27
  • 打赏
  • 举报
回复
引用 10 楼 sbwwkmyd 的回复:
[quote=引用 1 楼 sbwwkmyd 的回复:]类型转换至少需要类型判定操作,虚方法或者接口方法调用需要多一次地址跳转。
虚方法多一次寻址是相对于普通方法的,因为目标是不确定的。 如果父类的方法是虚方法,子类的重载方法同样也是虚方法,所以使用父类还是子类调用都是一样的。 接口方法比确定类型方法调用多一次查表操作。[/quote] 没太明白你的意思。 直接用this.接口方法() 和 ((接口)this).接口方法() 之间到底有什么性能上区别?
tcmakebest 2014-03-27
  • 打赏
  • 举报
回复
类型转换操作不会影响到类型本身,只是进行了一次类型判断,因为如果类型不对是要报错的。
showjim 2014-03-27
  • 打赏
  • 举报
回复
引用 20 楼 indusl 的回复:
求高人解答直接用 this.接口方法() 和 ((接口)this).接口方法() 之间到底有什么性能上区别? 后者的用法有什么优点?
降低了运行效率,没有什么优点。有时候不得不这么写,比如实现了两个接口,方法签名都一样。
indusl 2014-03-27
  • 打赏
  • 举报
回复
求高人解答直接用 this.接口方法() 和 ((接口)this).接口方法() 之间到底有什么性能上区别? 后者的用法有什么优点?
likevs 2014-03-27
  • 打赏
  • 举报
回复 1
有影响,难道楼主你觉得转换与不转换,都什么也没变,都一个样?不可能! 不过不明显罢了,你看ildasm.exe,会发现派生类会被标识扩展于哪个基类,这些标识在转换操作时有用, 那么,你转换语句给它,先不说栈里的地址指向有无变化,就单讲去验证类型的兼容性,多少得花些时间。 为毛一想到性能影响,就只想到大家都知道的像装箱与拆箱这种因栈和堆变更, 在我看来,写的代码不一样,害得编译器多生成几行CIL,都算是受影响的,只是影响的大小不同罢了。 当然,谁都希望这样做不受影响,但多态这玩意,真心好用实用,不能放弃
霜寒月冷 2014-03-27
  • 打赏
  • 举报
回复
没切实感觉到有多大危害,帮楼主顶下,期望有个正确的解释
indusl 2014-03-26
  • 打赏
  • 举报
回复
引用 4 楼 yi_piao 的回复:
其实上面还没有说明我的态度,我的态度就是在处理这类问题的时候,与其在性能的提升上花大量的时间做优化,不如把这些时间拿去实际中了解相关的业务来做流程上的优化更实际,代码只要能稳定的运行就没多大关系。
不是说做优化,而是.net框架里有大量的转化为接口类或父类的调用方法,必须要这样做吗?
indusl 2014-03-26
  • 打赏
  • 举报
回复
引用 5 楼 caozhy 的回复:
没有办法将子类“转换”成父类。所谓的“转换”,只是让编译器“视作”父类类型。因此根本没有任何开销。 当然这里有个例外,就是值类型,当它强制转换为object的时候,会发生装箱。
不考虑装箱,拆箱操作,只说引用类型。 “视作”父类型,为何没有开销?二楼说:“类型转换至少需要类型判定操作,虚方法或者接口方法调用需要多一次地址跳转。”, 那么除了必须用base.虚方法外,直接用this.方法。引用父类的方法不行吗,为何非要先转成父类或者接口类?
threenewbee 2014-03-26
  • 打赏
  • 举报
回复
没有办法将子类“转换”成父类。所谓的“转换”,只是让编译器“视作”父类类型。因此根本没有任何开销。 当然这里有个例外,就是值类型,当它强制转换为object的时候,会发生装箱。
yi_piao 2014-03-26
  • 打赏
  • 举报
回复
其实上面还没有说明我的态度,我的态度就是在处理这类问题的时候,与其在性能的提升上花大量的时间做优化,不如把这些时间拿去实际中了解相关的业务来做流程上的优化更实际,代码只要能稳定的运行就没多大关系。
yi_piao 2014-03-26
  • 打赏
  • 举报
回复
首先回答你的问题:类转换为基类,或基类(包含相关类的强类型)转换为相应类,都会有性能的损耗。 但是我感觉这种损失在大多数的情况是可以忽略不计的,除非你是写通讯类的应用或是对性能要求极高的程序才需要考虑。 比如说以下代码:

    int x=5;
    object obj=x;
    int y=(int) obj;
上面的代码纯演示,请不要考虑它有何意义。从性能的角度来说其产生了装箱,拆箱操作操作,好像影响了性能。 但是,如果只是针对企业应用,个人感觉这方面是不要做过多考虑的。比如你在做一个企业零售商店的进货流程,采购下单-供应商回签合同交期-企业收货这种流程往往很复杂,而且可以把流程做大量优化,比如以前的一个采购流程说不定要走10天,经过优化后只要5天,这样节省了5天的时间,而你的代码再怎么优化,也最多节约几秒钟的时间。
bdmh 2014-03-26
  • 打赏
  • 举报
回复
这样很危险,如果使用了子类才有的方法,就会报错
showjim 2014-03-26
  • 打赏
  • 举报
回复
类型转换至少需要类型判定操作,虚方法或者接口方法调用需要多一次地址跳转。 如果不是简单到可以内联的程序,基本上可以不用考虑。
加载更多回复(4)
PyTorch版的YOLOv8是先进的高性能实时目标检测方法。 TensorRT是针对英伟达GPU的加速工具。ONNX (Open Neural Network Exchange) 作为一个开放的网络模型中间表示(IR)格式,提供了跨框架兼容性。可以方便不同的框架轻松地交换模型,有助于框架之间的互操作性。本课程讲述如何对YOLOv8目标检测的PyTorch权重文件转成ONNX格式并进行TensorRT加速部署。相比与直接使用TensorRT API构建推理引擎,本方法更具灵活性,可用于YOLOv8网络架构修改后的模型部署。课程内容包括:YOLOv8目标检测的PyTorch权重文件转成ONNX格式,再转成TensorRT 推理引擎支持在GPU上端到端TensorRT加速部署,包括预处理(图像resize, 归一化)、网络推理、后处理(非极大抑制) 均在GPU上执行支持FP16加速提供C++和Python的TensorRT加速命令接口分别在Windows和Ubuntu系统上做YOLOv8的ONNX转换及TensorRT部署演示支持图片、图片文件夹、视频文件的TensorRT的加速推理提供YOLOv8的ONNX转换及TensorRT加速部署代码和代码解析文档实测推理速度提高2倍以上。课程内容包括:原理篇(YOLOv8网络架构与组件、TensorRT基础、ONNX基础、CUDA编程方法)实践篇(Windows和Ubuntu系统上的ONNX模型转换及TensorRT加速部署流程演示)代码解析篇(YOLOv8的ONNX模型转换及TensorRT加速的代码解析) 

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧