问题之源

C# 7.2推出了全新的参数修饰符in,据说是能提升一定的性能,官方MSDN文档描述是:

Add the in modifier to pass an argument by reference and declare your design intent to pass arguments by reference to avoid unnecessary copying.

然而,想当然地使用它却导致更多的副本出现,影响代码运行速度。

MSDN中还有一段隐含的副作用的描述:

You can call any instance method that uses by value parameters. In those instances, a copy of the in parameter is created.

同时文档也提到了readonly ref的目的:

After adding support for in parameters and ref redonly [sic] returns the problem of defensive copying will get worse since readonly variables will become more common.

来看一下MSDN里的这个例子::

private static double CalculateDistance(in Point3D point1, in Point3D point2)

{

double xDifference = point1.X - point2.X;

double yDifference = point1.Y - point2.Y;

double zDifference = point1.Z - point2.Z;

return Math.Sqrt(xDifference * xDifference + yDifference * yDifference + zDifference * zDifference);

}

假设Point3D类型是这样定义的:

public struct Point3D

{

public Point3D(double x, double y, double z)

{

X = x;

Y = y;

Z = z;

}

public double X { get; }

public double Y { get; }

public double Z { get; }

}

结果C#的几个本不相关的特性以一种闹心的方式结合起来:

  1. 标记了in的结构体参数是readonly只读的

  2. 调用标记为readonly的结构体的实例化方法将产生一个副本

  • 因为这个方法要通过改变this指针来达到确保标记了readonly的原值不会被修改

  • 属性访问器也是实例方法,受this影响

  • 每次给CalculateDistance方法传递标记了in的结构体参数时,编译器会在访问时自动为这个参数的每个属性创建一个副本,本以为不会创建副本,结果反而每个传进来的参数在方法内部弄出来3个!

    这个问题存在已久,看一下Jon Skeet的博客:The Surprising Inefficiency of Readonly Fields。只不过使用in让这个尴尬的场面更频繁易现了。

    解决方案

    解决办法同样来自C# 7.2:readonly struct.

    如果将public struct Point3D改成public readonly struct Point3D,因为所有字段也已经是readonly了,所以整个结构体都无需改变,编译器此时也会省掉副本的操作,只有这样才会出现结构体参数比按值传递获得更快的运行速度。

    不过注意在C# 7.1中结构体是可以通过标记ref来传参达到同样避免副本开销的。尽管如此,结构体参数的字段想要改变值仍是可变的,甚至这个结构体都可以指向另一个新的。在函数的参数列表中使用in的声明主要意图还是为了告诉调用者本函数不会去修改传进来的参数,当然编译器也会配合强制保证。

    示例

    这里有一个关于inrefstruct和readonly struct各种组合的性能测评(结构体size太小看不出差别,因此这个示例把结构体增加到56 bytes以便跑出更明显的对比效果)。结果如下:

    总结

    • 当使用in代替ref表示设计意图时,要明白在传递较大且较多的结构体时会有微小的性能损失

    • 当使用in又要避免产生副本或提高性能,在声明结构体时要使用readonly struct

    原文地址 http://www.cnblogs.com/BeanHsiang/p/8687780.html


    .NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
    
    

这个拖后腿的“in”相关推荐

  1. 2020 年 5 月程序员工资统计,平均 14542 元,我又拖后腿了!

    点击上方"视学算法",选择加"星标"置顶 重磅干货,第一时间送达 来源/作者:有数可据     转载自:算法爱好者 https://blog.csdn.net/ ...

  2. 2019宁波本科计算机招聘工资,@宁波人,76282!2019年度平均工资是这么多,你拖后腿了吗?...

    原标题:@宁波人,76282!2019年度平均工资是这么多,你拖后腿了吗? 今天,宁波市统计局发布2019年宁波市平均工资, 我市全社会单位就业人员年平均工资76282元,高于全省4759元.一起来看 ...

  3. 2021年6月程序员平均工资 15052,你给行业拖后腿了吗?

    上周我们发布了一篇名为<2021年6月程序员工资统计,平均15052元>的文章,引起了网友们的广泛讨论. 据文章中调查结果显示,"2021年6月全国招收程序员435501人,平均 ...

  4. 2018python好找工作吗-2018年IT行业薪资大揭秘:你拖后腿了吗?

    原标题:2018年IT行业薪资大揭秘:你拖后腿了吗? 现在就业形势较好和较差的行业分别是哪些?哪些地区用人需求大?又有哪些地方就业竞争激烈?这份报告快来了解一下! 从报告可以看出,分行业来看,就业景气 ...

  5. 2020 年 4 月全国程序员工资新鲜出炉,我拖后腿了!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~ 看到脉脉上一网友分享程序员4月份工资,平均工 ...

  6. dba的前景_2019年DBA薪资大起底,你拖后腿了吗?

    作者:ADMIN,云和恩墨DBA 摘要:作为IT行业薪酬排行榜中薪酬最高的十大职业之一,数据库行业收入都是金领级别的.想知道自己的薪资给DBA平均薪资拖后腿了吗?看完这篇文章你就知道了! 数据库管理员 ...

  7. 【程序员薪资】2021年04月新鲜出炉,看看你拖后腿了吗?

    程序员一直都是一个备受人们关注的群体.据IDC统计,全球约有1850万名程序员(数据还在持续增长),中国占10%左右.随着近年全国互联网创业热潮的兴起,"互联网+"."云 ...

  8. 做人真善美,做事拖后腿

    >>蒋锡培:成大事者,境界一定越来越高,身段一定是越来越低,做人真善美,做事稳准狠.有两种反面教材,一种是做人真善美,做事拖后腿;一种是做人假丑恶,做事稳准狠.前一种的悲剧在于误事误人,且 ...

  9. 2020 大厂研发岗薪酬排名出炉,看完我真的拖后腿了。。。

    本文来源:https://duibiao.info/2020 我们对2020年国内互联网公司的薪酬按照职级做了排名. 为了统一不同公司之间的职级体系,我们以初级,中级,高级和资深工程师来统计薪酬.为了 ...

  10. 全球Python开发者平均年薪5.6万美元,你拖后腿了吗?

    每年,Stack Overflow都会做关于开发者的调查,从开发者最喜欢的技术到工作偏好.今年是Stack Overflow发布年度开发者报告的第八年,也是受访者数量最多的一年. 今年1月,有超过10 ...

最新文章

  1. Vscode 调试 Flutter 项目
  2. 利用序列化与反序列化对Java对象进行深度复制
  3. UART 和 USART 的区别 == 通用异步收发传输器 通用同步/异步串行接收/发送器
  4. matlab电话拨号音的合成与识别代码,实验报告 电话拨号音的合成与识别
  5. [解决]Win7 操作系统不能安装VMware
  6. 关于thinkphp5的报错 mkdir() Permission denied的解决
  7. 没写client,想先测试server端怎么办?
  8. db2存储结构换Oracle,DB2中实现Oracle的功能
  9. linux安装mysql5.5.52,Linux系统上安装MySQL 5.5prm
  10. 2017-2018-1 20155202 《信息安全系统设计基础》第4周学习总结
  11. 初窥JQuery(二)-事件机制(1)
  12. LQR控制基本原理(包括Riccati方程具体推导过程)
  13. access open 知乎_必备技能!国际汇款SCI Open Access费用
  14. java布道师_我和 Spring 技术布道师的一天
  15. finalcut剪切快捷键_Final Cut Pro X 常用键盘快捷键
  16. jQuery-动画效果(王者荣耀手风琴案例)
  17. 计网day12 奈氏准则和香农定理
  18. 电脑硬件知识入门之硬盘篇
  19. 【企业动态】开启新征程,谱写新篇章 | 数商云喜迎乔迁
  20. 【整理】Matlab常用函数

热门文章

  1. 【leetcode】521. Longest Uncommon Subsequence I
  2. 移动工具V和选区工具M
  3. JAVA 排序工具类
  4. std::thread 不 join
  5. 当前联机日志损坏恢复
  6. C++学习之路: 线程封装(基于对象编程)
  7. 在web网页中正确使用图片格式
  8. C# 发出异步的Get请求
  9. .NET 6新特性试用 | 文件范围的命名空间
  10. .NET生态现状:超一半 .NET开发者使用C# 8、.NET Framework使用量减少