gpt4 book ai didi

c# - Buffer.BlockCopy vs Array.Copy 好奇心

转载 作者:太空狗 更新时间:2023-10-29 22:15:30 74 4
gpt4 key购买 nike

我一直在研究一些 .NET 功能(即管道、内存和数组池)以实现高速文件读取/解析。在使用 Array.CopyBuffer.BlockCopyReadOnlySequence.CopyTo 时,我遇到了一些有趣的事情。 IO 管道以 byte 形式读取数据,我正在尝试有效地将其转换为 char

在使用 Array.Copy 时,我发现我可以从 byte[] 复制到 char[] 和编译器(和运行时)非常乐意这样做。

char[] outputBuffer = ArrayPool<char>.Shared.Rent(inputBuffer.Length);
Array.Copy(buffer, 0, outputBuffer, 0, buffer.Length);

此代码按预期运行,但我确定此处未正确处理一些 UTF 边界情况。

我的好奇心来自 Buffer.BlockCopy

char[] outputBuffer = ArrayPool<char>.Shared.Rent(inputBuffer.Length);
Buffer.BlockCopy(buffer, 0, outputBuffer, 0, buffer.Length);

outputBuffer 的结果内容是垃圾。例如,buffer 的示例内容为

{ 50, 48, 49, 56, 45 }

复制后outputBuffer的内容为

{ 12338, 14385, 12333, 11575, 14385 }

我只是好奇 CLR 内部“幕后”发生了什么导致这 2 个命令输出如此不同的结果。

最佳答案

Array.Copy() 对元素类型更智能。它将尝试尽可能使用 memmove() CRT 函数。但是会回退到一个循环,在它不能复制每个元素时。根据需要转换它们,它考虑装箱和原始类型转换。因此源数组中的一个元素将成为目标数组中的一个元素。

Buffer.BlockCopy() 跳过所有这些并使用 memmove() 爆炸。不考虑转换。这就是为什么它可以稍微快一点的原因。并且更容易误导您有关数组内容的信息。请注意,utf8 编码的字符数据在该数组中是可见的,12338 == 0x3032 = "2 ",14385 = 0x3831 = "18",等等。使用 Debug > Windows > Memory > Memory 1 更容易看到。

也许值得注意的是,这种类型强制一个特性。假设您通过套接字或管道接收到一个 int[] 但数据在 byte[] 缓冲区中。迄今为止最快的方法。

关于c# - Buffer.BlockCopy vs Array.Copy 好奇心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51810410/

74 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com