写点什么

C#的未来:托管指针

  • 2015-05-05
  • 本文字数:1388 字

    阅读完需:约 5 分钟

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

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

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

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

Ref 返回值与 Ref 本地变量这条提议中,提出了另外两种能够为 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(
Func 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 参数。换句话说,编译器将强迫你不能够返回某个指向本地变量的引用。

查看英文原文: C# Futures: Managed Pointers

2015-05-05 09:573138
用户头像

发布了 428 篇内容, 共 190.8 次阅读, 收获喜欢 39 次。

关注

评论

发布
暂无评论
发现更多内容

TLM算法仿真5G毫米波手机天线和整机

思茂信息

5G 仿真 CST Studio Suite

质量管理中的IQC、PQC、FQC、OQC

积木链小链

质量管理 数字化 智能制造

一键部署 Dify + MCP Server,高效开发 AI 智能体应用

阿里巴巴云原生

AI阅读眼动就翻页,领权益解锁HUAWEI Pura X内容新体验

最新动态

热门活动速递 | AI 原生应用开发实战营·深圳站

阿里巴巴云原生

阿里云 云原生

内部聊天软件,BeeWorks-安全的企业内部通讯软件

BeeWorks

即时通讯 IM 私有化部署 局域网视频软件

出版社题库管理系统的技术架构

北京木奇移动技术有限公司

软件外包公司 出版社 题库管理系统

重构智能设备管理范式:火山引擎端智能解决方案上新,多重 AI 服务即刻享用!

火山引擎开发者社区

云智赋能,绘就农业强国新图景!

天翼云开发者社区

智慧农业 数字孪生 农业数字化

AI与智能客服:如何让AI为企业提供更高效、更人性化的客户服务?

天津汇柏科技有限公司

人工智能 智能客服 AI 人工智能

人工智能与网络安全:AI如何预防、检测和应对网络攻击?

天津汇柏科技有限公司

人工智能 网络安全 AI 人工智能

巴塞罗那对阵塞尔塔:一场事关竞逐西甲联赛冠军与冲击欧战资格的较量

新消费日报

欢迎 Apache SeaTunnel 新晋 Committer 王超

白鲸开源

25年IT信息安全靠谱保障办法看这里!

行云管家

网络安全 信息安全 IT安全

行业热点丨为什么AI驱动工程对汽车设计和轻量化至关重要?

Altair RapidMiner

人工智能 AI 汽车 数字孪生 CAE

K8S 部署 Deepseek 要 3 天?别逗了!Ollama+GPU Operator 1 小时搞定

北京好雨科技有限公司

k8s rainbond 企业号 4 月 PK 榜 gpu 算力 DeepSeek R1 模型

2025 全球分布式云大会演讲实录 | 沈建发:智启边缘,畅想未来:边缘计算新场景落地与 Al 趋势新畅想

火山引擎边缘云

人工智能 边缘计算 AI 大底座 边缘智能

超实用!用FunctionCall实现快递AI助手

王磊

深入研究:1688商品跨境属性API接口详解

tbapi

1688API 1688跨境代采 1688商品属性接口 1688跨境属性接口

出版社题库管理系统的技术难点

北京木奇移动技术有限公司

软件外包公司 出版社 题库系统开发

抖音电商如何用扣子 Coze 打造 AI 客服?

火山引擎开发者社区

CommunityOverCode Asia 2025议题征集倒计时,DataOps 分论坛等你发声

白鲸开源

出版社题库管理系统的测试

北京木奇移动技术有限公司

软件外包公司 出版社 题库系统开发

乐言科技:云原生加速电商行业赋能,云消息队列助力降本 37%

阿里巴巴云原生

阿里云 云原生

在BeeWorks中,网盘和即时通讯如何互相集成?

BeeWorks

即时通讯 IM 企业级应用

域名有哪些状态?不同的域名状态分别代表什么意思?

国科云

广告营销行业使用堡垒机的场景简单聊聊

行云管家

网络安全 信息安全

AI重构商品计划管理:时尚品牌决胜未来的四大核心能力

第七在线

如何开拓亚洲加密货币市场?一文解析亚洲国家差异、用户行为及市场特征

TechubNews

加密市场

ArkUI-X 5.0.4 Release:跨平台开发的全新体验

坚果

鸿蒙 HarmonyOS 坚果派

[方法讨论]手机号码批量导入手机通讯录,导入苹果iphone通讯录华为手机小米手机等安卓手机

一码平川

C#的未来:托管指针_.NET_Jonathan Allen_InfoQ精选文章