[关闭]
@Rays 2017-05-15T09:05:39.000000Z 字数 2393 阅读 1698

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

Microsoft


摘要: 显然Microsoft开发人员和管理人员并没有表达清楚,事实上ASP.NET Core 2.0将会得到整个.NET Framework的支持。当前的更改只实现了在ASP.NET上提供.NET Core,这是为了便于开发而采取的一个临时步骤。即便是临时性更改,一个依然需要解决的问题是:要想进一步改进ASP.NET的性能,需要提供更好的字符串处理库。

作者: Jonathan Allen

正文:

显然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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注