Lev*_* M. 5 c# optimization binaryfiles
我有以下代码片段,用于读取二进制文件并验证它:
FileStream f = File.OpenRead("File.bin");
MemoryStream memStream = new MemoryStream();
memStream.SetLength(f.Length);
f.Read(memStream.GetBuffer(), 0, (int)f.Length);
f.Seek(0, SeekOrigin.Begin);
var r = new BinaryReader(f);
Single prevVal=0;
do
{
r.ReadUInt32();
var val = r.ReadSingle();
if (prevVal!=0) {
var diff = Math.Abs(val - prevVal) / prevVal;
if (diff > 0.25)
Console.WriteLine("Bad!");
}
prevVal = val;
}
while (f.Position < f.Length);
Run Code Online (Sandbox Code Playgroud)
不幸的是,它运行速度非常慢,我正在寻求改进。在 C++ 中,我只需将文件读入字节数组,然后将该数组重新转换为结构数组:
struct S{
int a;
float b;
}
Run Code Online (Sandbox Code Playgroud)
我将如何在 C# 中执行此操作?
使用与您的 C++ 代码完全相同的显式布局 ( )定义一个struct(可能是 a ),然后是以下之一:readonly struct[StructLayout(LayoutKind.Explicit)]
unsafe在原始指针上使用代码,或Unsafe.AsRef<YourStruct>在数据上使用,并Unsafe.Add<>进行迭代T,并迭代跨度byte[]; 创建一个Span<byte>,byte[]然后使用MemoryMarshal.Cast<,>创建一个Span<YourType>,并迭代它byte[]; 用于fixed固定byte*并获取指针;使用unsafe代码遍历指针Pipe是缓冲区,可能用于StreamConnection填充FileStream管道,以及从管道出队的工作循环;复杂性:缓冲区可能不连续,并且可能在不方便的地方分割;只要第一个跨度不是至少 8 个字节,就需要可解决的但微妙的代码(或这些概念的某种组合)
其中任何一个都应该像 C++ 版本一样工作。第四个很简单,但对于非常大的数据,您可能更喜欢内存映射文件
| 归档时间: |
|
| 查看次数: |
1612 次 |
| 最近记录: |