当它包含char数组时快速读取C结构

Mor*_*rat 8 c# performance struct unsafe c++-cli

我有以下C结构

struct MyStruct {
    char chArray[96];
    __int64 offset;
    unsigned count;
}
Run Code Online (Sandbox Code Playgroud)

我现在有一堆用C语言创建的文件,里面有成千上万的结构.我需要使用C#读取它们,速度是一个问题.

我在C#中做了以下几点

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 108)]
public struct PreIndexStruct {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 96)]
    public string Key;
    public long Offset;
    public int Count;
}
Run Code Online (Sandbox Code Playgroud)

然后我用文件从文件中读取数据

using (BinaryReader br = new BinaryReader(
       new FileStream(pathToFile, FileMode.Open, FileAccess.Read, 
                      FileShare.Read, bufferSize))) 
{
    long length = br.BaseStream.Length;
    long position = 0;

    byte[] buff = new byte[structSize];
    GCHandle buffHandle = GCHandle.Alloc(buff, GCHandleType.Pinned);
    while (position < length) {
        br.Read(buff, 0, structSize);
        PreIndexStruct pis = (PreIndexStruct)Marshal.PtrToStructure(
            buffHandle.AddrOfPinnedObject(), typeof(PreIndexStruct));
        structures.Add(pis);

        position += structSize;
    }
    buffHandle.Free();
}
Run Code Online (Sandbox Code Playgroud)

这非常有效,我可以从文件中检索数据.

我已经读过,如果不使用GCHandle.Alloc/Marshal.PtrToStructure,我可以使用C++/CLI或C#不安全代码来加速.我找到了一些例子,但它们只引用没有固定大小数组的结构.

我的问题是,对于我的具体情况,是否有更快的方式使用C++/CLI或C#不安全代码?

编辑

其他性能信息(我使用过ANTS Performance Profiler 7.4):

调用Marshal.PtrToStructure时,我占用了66%的CPU时间.

关于I/O,105ms中只有6个用于从文件中读取.

Sim*_*ier 4

在这种情况下,您不需要明确使用 P/Invoke,因为您不必在托管代码和本机代码之间来回传递结构。所以你可以这样做。它将避免这种无用的 GC 句柄分配,并仅分配需要的内容。

public struct PreIndexStruct {
    public string Key;
    public long Offset;
    public int Count;
}

while (...) {
    ...
    PreIndexStruct pis = new PreIndexStruct();
    pis.Key = Encoding.Default.GetString(reader.ReadBytes(96));
    pis.Offset = reader.ReadInt64();
    pis.Count = reader.ReadInt32();
    structures.Add(pis);
}
Run Code Online (Sandbox Code Playgroud)

我不确定你能比这快得多。