博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#的未来:托管指针
阅读量:6648 次
发布时间:2019-06-25

本文共 1668 字,大约阅读时间需要 5 分钟。

对于许多开发者,尤其是编写游戏软件,以及进行纯数字计算的开发者来说,原始性能是程序的重中之重。同时对他们来说,最大的问题莫过于内存分配了。虽然分配操作本身消耗很小,但过多的分配会造成内存的极大压力,并且造成垃圾回收器的执行周期更加频繁。

\\

在堆中分配的内存也会造成缓存的问题。如果你有一个存放引用类型的列表或是数组,它的实际数据与数组本身是分开进行保存的。这意味着你可能不得不浪费更多的缓存线以保存这个数组以及由数组所引用的对象。而如果我们在同一时间内创建了这些对象,那么可能会造成很大的分散性,进而导致消耗更多的缓存线。相关数据的分散性也就导致了糟糕的局部性(locality)。

\\

使用值类型(在C#的说法中也就是结构体)能够极大地减少内存的分配次数并改善局部性。但是,在结构体的使用上存在着一些限制。因为设计它们的初衷是传递拷贝,因此你必须保证它们的尺寸非常小,否则就很可能受到性能上的严惩,这也违背了在第一时间使用值类型的本意。

\\

为了避免无意义的拷贝,一种做法是在将值类型传递给函数时使用一个托管指针。目前为止,唯一一种能够在C#中创建托管指针的做法是在参数前使用“ref”关键字。这种做法确实能够应对某些场景的性能问题,但实际上CLR通过托管指针能够实现的功能远不止这些。

\\

在这条提议中,提出了另外两种能够为C#程序员所用的选项。

\\

Ref本地变量

\\

假设有一个int类型的本地变量a,这条提议允许你通过以下语法创建一个Ref本地变量:

\\

ref int x = a;

\\

类似于ref参数,ref本地变量本质上就是它所指代的本地变量的某个别名而已,这种方式使你不必再生成它的拷贝。你也可以通过这种语法创建一个指向某个数组元素、或指向另一个对象的某个字段的指针。

\\

ref int y = b[2];\

ref int z = c.d;

\\

在CLR术语中,Ref本地变量被称为一个“TypedReference”(类型化引用)。一个TypedReference包含了指向某个地址的指针,同时也包含了该地址所能够存放的数据的类型信息。

\\

按规定,一个TypedReference必须是一个参数或本地变量。这一规定是因为CLR不允许堆中的元素指向其它元素的内部。你也无法返回一个TypedReference对象,否则你就可以返回一个对本地对象的引用,而这个对象在函数结束后自然是已经不存在了。

\\

Ref返回值

\\

这条提议的第二部分允许你在函数中返回ref引用,这就使以下场景变得可能:

\\

public static ref TValue Choose\u0026lt;TValue\u0026gt;(\

    Func\u0026lt;bool\u0026gt; condition, ref TValue left, ref TValue right)\\
{\\
    return condition() ? ref left : ref right;\\
}\\
Matrix3D left = […], right = […];\\
Choose(chooser, ref left, ref right).M20 = 1.0;

\\

通过使用这种新语法,以上的示例代码就不会对结构体进行任何拷贝操作,而是创建托管指针并在方法调用中进行传递。

\\

与ref本地变量不同,要实现这一特性或许必须对CLR标准进行改动。正如之前所说,通常来说是不允许返回TypedReference对象的。从技术上讲你可以这么做,但这种操作不是类型安全的,其结果也是“无法检验的”。在受限安全设置中,使用未经检验的代码是不允许的,因为它可能会引起严重的bug,因此一般只在C与C++中使用。

\\

为了缓解这一风险,这条提议中也表示,你所返回的引用必须指向堆中的某个对象,或是指向某个已经存在的ref或out参数。换句话说,编译器将强迫你不能够返回某个指向本地变量的引用。

\\

查看英文原文:

转载地址:http://slrvo.baihongyu.com/

你可能感兴趣的文章
cas
查看>>
Linux新手之路 - gzip bzip2 tar
查看>>
Vmware虚拟机的网络连接的桥接模式
查看>>
《Spring In Action 》学习笔记之POJO重写equals和hashCode
查看>>
我的友情链接
查看>>
Windows地址转译方法
查看>>
6.Python深浅拷贝
查看>>
用它开启新的文档协作模式,工作效率提升100%!
查看>>
上传本地文件至GitHub
查看>>
双色球--最多2个号码相同的内幕
查看>>
谷歌与世界大脑
查看>>
JavaScript: The Definitive Guide 权威指南,读书笔记(三)
查看>>
GBin1在线实例帮助你更好的了解jQuery功能特性(一)
查看>>
邮件系统安装与使用过程中各种报错与问题的详细解决方法
查看>>
which whereis find locate 的区别
查看>>
C语言内嵌汇编
查看>>
Android EditText
查看>>
java取消线程实例
查看>>
基于MaxCompute的图计算实践分享-Resolver简介
查看>>
聊聊flink的FsCheckpointStorage
查看>>