BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

ASP.NET Core改进了.NET Framework中的字符串处理

| 作者 Jonathan Allen 关注 595 他的粉丝 ,译者 Rays 关注 3 他的粉丝 发布于 2017年5月16日. 估计阅读时间: 6 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

显然Microsoft开发人员和管理人员并没有表达清楚,事实上ASP.NET Core 2.0将会得到整个.NET Framework的支持。当前的更改只实现了在ASP.NET上提供.NET Core,这是为了便于开发而采取的一个临时步骤。对此,在ASP.NET Core预览发行声明中给出了如下的解释:

在发布ASP.NET Core 2.0预览版时,仅提供了对.NET Core 2.0 SDK的支持。我们的目标是在.NET Standard 2.0中发布ASP.NET Core 2.0,使应用可运行在.NET Core、Mono和.NET Framework上。团队正致力于在Build大会之前解决最后一些问题,最突出的问题是在ASP.NET Core 2.0预览版中使用了.NET Standard 2.0之外的API,这妨碍了在.NET Framework上的运行。由于这些问题,我们限制了Preview 1版本对.NET Core的支持,以免对开发人员在.NET Framework上将ASP.NET Core 1.x应用升级到ASP.NET Core 2预览版时造成破坏。

在Register的一次采访中,Miguel de Icaza确认了Microsoft对.NET Framework的承诺

我要对此做出澄清。我感到十分遗憾的是,即将推出的.NET Core 2.0是我们专为Build大会准备,它只是一个预览版,因为我们发现其中存在一系列在.NET Framework上无法很快得到解决的问题。因此,我们推出的软件包仅支持在.NET Core 2.0上运行ASP.NET Core 2.0。我们将会修复这个问题,.NET Core 2.0终将运行在.NET Framework上。

即便是临时性更改,一个依然需要解决的问题是:要想进一步改进ASP.NET的性能,需要提供更好的字符串处理库。

内存分配上的考虑

在.NET中,几乎所有的字符串处理方法都要做内存分配,该问题长期以来一直为人所诟病。在解析JSON、XML等格式时,substring方法常会产生成百上千的微小字符串分配。这不仅耗费了大量时间生成拷贝,而且对垃圾回收造成了很大的压力。这并非应用开发人员所能掌控的。

这种做法有其合理性。与.NET一样,在Java中字符串也是不可变的。而Java自带的substring方法并不分配新的字符串,它创建一个指向原始字符串的指针。虽然Java的substring方法无需分配内存,但是存在着内存泄漏的风险。一个字符串substring方法可以保留5MB字符串不被垃圾回收(这个问题相当恶劣,因此在Java 1.7u6版中做了更改,substring方法做内存分配)。

在“Span<T>建议”中,开发人员可以选择使用两种不同的substring方法,即分配内存的方法和不做内存分配的方法。ASP.NET Core所使用的解析库也可以被覆写,在内部使用不分配内存的substring方法。但在解析操作的最后阶段,需要确保释放所有Span<char>的实例。

这一更改还需要重新实现更高效的基本类型解析方法,例如Int32.Parse和Inta32.TryParse等。理想情况下,这些方法将会加入到基类库(BCL,Base Class Library)中,而不是以单独库的方式提供。这就回到了.NET Framework、Standard和Core的对比问题上。

毫无疑问,可以加快对.NET Core的更改过程。除了操作系统特定的功能,新特性将做优先更改。否则,只有得到所有.NET/Mono的各种实体(incarnation)支持的新特性,才会出现在.NET Standard中。虽然从理论上讲,这些实体也归属于Microsoft的,但是新特性的添加依然会是一个冗长的过程。

因此,在开发ASP.NET Core的过程中,基于ASP.NET进行构建是合乎情理的。这使得新的API在提交标准化前,得到真实用例的精炼。

默认编码上的考虑

并非所有开发人员都了解,在.NET内部使用的是UTF16字符串。除了实现文件或网络I/O处理之外,对于大部分用例,开发人员都无需考虑编码问题。

Web应用主要基于UTF8编码。同样,在处理大部分用例时,服务器端开发人员也无需考虑编码问题。只需确保无论使用何种内部格式,最终都会转换为UTF8编码。

当需考虑性能时,这种做法就存在问题。所有的Web请求最初都是以UTF8编码的,需要在被.NET理解前转化为UTF16编码。反之,所有来自.NET服务器的响应,需要由UTF16编码转化为UTF8编码。

现在已有一些建议方法,意在消除这种转换的必要。一种做法创建了Utf8String类并匹配字符串处理库,之后就可以新建直接操作类的解析库。这一做法是完全“明确征得同意”(Opt In)的,因此风险很低。

更全面的建议是由Matt Warren提出的,称为“紧凑字符串(Compact String)实现”。该建议受到了OpenJDK中类似建议的启发,它会在字符串中添加一个类型字段,用于指示所使用的编码。这是一种更大程度上的更改,对Span<T>存在一些负面影响。

查看英文原文:What ASP.NET Core May Bring to the .NET Framework’s String Handling

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

社区的力量不少 by SONG JRoger

在大家激烈讨论后,MS还是按大家的意思来了。或者真如文中所说。

Re: 社区的力量不少 by Rays InfoQ

正是如此。substring做内存分配还是做指针,两者之间在性能和安全性上一直存在着权衡。
社区意见偏向于性能,由程序逻辑(包括额外字段)保证使用中的安全性。

Re: 社区的力量不少 by Rays InfoQ

正是如此。在substring是分配内存还是做指针上,一直在性能和安全性上存在着权衡。
社区倾向于指针,而安全性由程序逻辑表示(包括添加字段)。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

3 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT