我一直在使用一些.NET功能(即管道,内存和数组池)来进行高速文件读取/解析.我碰到的东西,而与玩弄有趣的Array.Copy,Buffer.BlockCopy和ReadOnlySequence.CopyTo.IO Pipeline将数据读取为,byte并且我正在尝试有效地将其转换为char.
在玩弄时Array.Copy我发现我能够从中复制byte[]到char[]编译器(和运行时)非常乐意这样做.
char[] outputBuffer = ArrayPool<char>.Shared.Rent(inputBuffer.Length);
Array.Copy(buffer, 0, outputBuffer, 0, buffer.Length);
Run Code Online (Sandbox Code Playgroud)
这段代码按预期运行,但我确信这里没有正确处理一些UTF边缘情况.
我的好奇心随之而来 Buffer.BlockCopy
char[] outputBuffer = ArrayPool<char>.Shared.Rent(inputBuffer.Length);
Buffer.BlockCopy(buffer, 0, outputBuffer, 0, buffer.Length);
Run Code Online (Sandbox Code Playgroud)
由此产生的内容outputBuffer是垃圾.例如,使用bufferas 的示例内容
{ 50, 48, 49, 56, 45 }
Run Code Online (Sandbox Code Playgroud)
outputBuffer复制后的内容是
{ 12338, 14385, 12333, 11575, 14385 }
Run Code Online (Sandbox Code Playgroud)
我只是好奇CLR内部正在发生的事情,导致这两个命令输出这些不同的结果.
Han*_*ant 13
Array.Copy()更聪明的元素类型.它会尝试使用memmove()CRT函数.但是当它不能复制每个元素时,它将回退到一个循环.根据需要转换它们,它会考虑装箱和原始类型转换.因此,源数组中的一个元素将成为目标数组中的一个元素.
Buffer.BlockCopy()跳过所有这些并使用memmove()进行爆炸.不考虑转换.这就是它可以稍微快一点的原因.更容易误导你关于数组内容.请注意,utf8编码的字符数据在该数组中可见,12338 == 0x3032 ="2",14385 = 0x3831 ="18"等.使用Debug> Windows> Memory> Memory 1更容易看到.
值得注意的是,这种类型强制是一个特征.说当你通过套接字或管道接收int []但是在byte []缓冲区中有数据时.到目前为止最快的方式.
| 归档时间: |
|
| 查看次数: |
406 次 |
| 最近记录: |