【问题标题】:Is there a MemoryStream that accepts a Span<T> or Memory<T>?是否有接受 Span<T> 或 Memory<T> 的 MemoryStream?
【发布时间】:2020-08-28 15:33:09
【问题描述】:

我正在从多个来源(MemoryMappedFiles 或 FileStream)读取数据。一个问题是每次读取字节、整数或其他类型的调用都非常慢。所以我想把一大块数据读入一个数组,然后把它交给一个轻量级的内存流,然后读取那里的各个组件。

问题是 .NET 的当前 MemorySrream 确实只允许在构造函数中使用数组,但我需要一个能够处理 Span 或 Memor 的 Stream。有一个 ReadOnlyMemoryStream 作为一个深埋在 .NET 源代码中的内部类。

有趣的是,尽管 ReadOnlyMemoryStream 比 MemoryStream 慢,但我认为它不应该有很大的不同。

有没有更好的实现方式?

【问题讨论】:

  • Span&lt;T&gt; 不能工作,因为它是仅堆栈的并且不能是像MemoryStream 这样的堆分配类的一部分。应该可以在Memory&lt;T&gt; 上创建一个 Stream,但我不知道这样的实现。
  • @KlausGütter:你当然是对的。似乎我需要创建自己的类,一个是 ref 结构,一个是常规结构或类,以便我可以使用 Span 或 Memory。我知道的 .NET Core 源类中唯一可用但内部的类是 ReadOnlyMemoryStream,它接受 Memory.

标签: c# .net .net-core


【解决方案1】:

如果您有 Span,那么您的速度已经很快了,只需直接通读即可,而不是在上面添加流。

Span 甚至可以让您访问真正漂亮的东西,例如直接的 struct 映射而没有副本 (MemoryMarshal.Cast)、跨度增量(相当于流前进,是 Unsafe.Add 的一部分),如果实际上是块副本必要的 (Unsafe.Copy) 等。

【讨论】:

  • 当然,但是 Stream 提供了额外的方法(例如使用 binaryreader)。我编写了自己的扩展方法。您当然是正确的直接这样做,但问题仍然是为什么 MemoryStream 比 ReadOnlyMemoryStream (使用 Span)快。
  • 如果这是问题所在,那么您的帖子标题错误。至于BinaryReader,它的所有方法也是MarshalMemoryMarshal 的一部分,也可以在原始Spans 上使用。
【解决方案2】:

是的,有这样的扩展方法,由Microsoft.Toolkit.HighPerformance包提供

【讨论】:

  • 感谢您的信息。我知道 Toolkit,但我没有看过扩展方法。
  • 不过,这是一个内部类。如果您使用的是 NuGet 包,则无法轻松访问它。
猜你喜欢
  • 1970-01-01
  • 2022-01-14
  • 2018-12-24
  • 1970-01-01
  • 2019-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多