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个用于从文件中读取.
在这种情况下,您不需要明确使用 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)
我不确定你能比这快得多。