System.Span 的构造函数采用 int 长度,并且该长度在内部存储为 32 位值。
但是,默认填充无论如何都会使结构的大小为 16 字节,因此 32 位长度不会节省任何空间。
https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/Span.Fast.cs
Span的设计文档没有提到这一点。 https://github.com/dotnet/corefxlab/blob/master/docs/specs/span.md
要获得权威答案,您必须询问设计和实现 .NET 的 .NET 团队Span<T>。那是说……
.NET 本质上是一个 32 位框架。它支持64位进程,并且可以从64位虚拟地址空间进行分配。但它对对象有 2GB 的限制。这导致了另一种设计选择:集合大小是 32 位整数,并且它们是有符号的,因为符合 CLS 的代码不使用无符号值。这两种设计选择相辅相成,相辅相成。
因此,当涉及到Span<T>旨在提供托管上下文中现有内存的子集时,该类型提供的公共接口与 CLS 要求兼容。因此,Length属性和索引器参数都是 32 位整数类型,也是Span<T>指定现有内存中的偏移量和长度的构造函数的参数。
这与 .NET API 的其余部分一致,其中数组和其他集合的元素不得超过 2^32 个,且不能大于 2GB。
其他相关阅读:
64 位 VB.NET 分配 > 2GB RAM(.NET 错误?)
我如何知道给定类型的 .net 数组可以分配的实际最大元素数?
BigArray,绕过 2GB 数组大小限制
问题的答案似乎是 Span 想要匹配具有附加 4 字节字段的 Memory。
https://github.com/dotnet/corefx/issues/26603#issuecomment-370419371
当前版本的 Memory 在 x64 上很好地打包为 16 字节,而 Span 似乎有空间用 IntPtr _length 替换 int _length 并且仍然适合 8/16 字节。但是,增加 Span 的 Lenght 属性需要对 Memory 执行相同的操作。如果我没记错的话,增加内存大小(从 16 字节到 24 字节)可能会对代码的性能产生影响,这会影响每个人。(不仅仅是我们这些使用大块内存区域的人)
确实,在我介绍的情况下,ReadOnlySequence 可以有效替代启用 64 位的内存/跨度,因为我所需要的只是将数据复制到某个地方。但是,当您需要在不复制的情况下读取/解码时,API 可能确实不太简单。
| 归档时间: |
|
| 查看次数: |
794 次 |
| 最近记录: |