<分区>
我正在使用 C# 中的程序访问共享内存(用 C 代码创建)。
内存映射文件的内容由表示必须用 C# 处理的文本的字节组成。
编码问题不是这里的问题...
基本上,C 代码将文本写入共享内存并将写入索引(在共享内存的开头)递增到下一个写入位置。在内存的末尾,索引环绕并从 0 开始。
为了在 C# 中读取,我维护了一个读取索引(也在共享内存的开头),只要两个索引不相等,我就在 C# 中处理数据。管理这两个指数是有效的,不应该是这个问题的问题。
只要写入索引不等于读取索引,C 代码就只能写入新数据 - 因为那样数据就会丢失。
在 C# 中,我使用 MemoryMappedFile
对象,并使用 MemoryMappedViewAccessor
对象访问字节。从这个 View 访问器我得到一个 IntPtr
:
这段代码是我项目的摘录,它按预期工作......
public MemoryMappedFile mmf;
public MemoryMappedViewAccessor mma;
public byte* pointer;
public void Init()
{
mmf = MemoryMappedFile.OpenExisting("MyFileMappingObject", MemoryMappedFileRights.ReadWrite);
mma = mmf.CreateViewAccessor(0, 0, MemoryMappedFileAccess.ReadWrite);
mma.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
}
我尝试使用流访问共享内存,但这比使用不安全的 IntPtr
变量要慢。
必须读取字节并将其转换为 C# 字符串。因为我必须进行一些解释和重新格式化,所以我不能简单地获取所有字节并将它们一步转换为 C# 字符串。
所以我最终调用了很多向现有字符串添加 C# 字符串的调用:
string zeile = string.Empty;
while (!eof())
{
string newpart = GetTextFromSharedMemory(); // this works fine
zeile = zeile + newpart; // Makes problems
}
如果我测量处理一定数量文本的时间(一次遍历整个共享内存),仅 GetTextFromSharedMemory() 可能需要大约 50 毫秒。所以这不是瓶颈。
只要我将 newpart
字符串添加到 zeile
字符串中,我的处理时间就会增加 5 到 6 秒(而我处理了大约 4 198 528 字节的数据在共享内存中,这大约是 2048 行 2048 字节)
这意味着比仅从共享内存中读取要长 100 倍。
如何使这些字符串连接更有效?
在将它们转换为字符串之前,我尝试将文本部分读出为字节并将字节列表连接在一起。这很有帮助,但我必须处理单个字节来解释和重新格式化...
在执行期间分配和处置许多字符串可能会触发垃圾收集器,这也可能对性能产生负面影响。
因为 C# 中的处理时间非常“糟糕”,共享内存最终会被填满,然后 C 代码必须等待它被清空才能添加更多数据。但这会影响其他进程的性能......