c# - 在处理共享内存和字符串时提高性能

标签 c# string performance

<分区>

我正在使用 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 代码必须等待它被清空才能添加更多数据。但这会影响其他进程的性能......

最佳答案

使用 StringBuilder 附加字符串。众所周知,简单字符串的字符串追加操作效率低下,因为字符串是不可变的。

StringBuilder zeile = new StringBuilder();
while (!eof())
{
   string newpart = GetTextFromSharedMemory(); // this works fine
   zeile.Append(newpart); 
}

然后使用zeile.ToString()获取最后的字符串值。

关于c# - 在处理共享内存和字符串时提高性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58634183/

相关文章:

java - 如何使用java中的方法从大字符串中删除相同的字符

mysql - 带有时间戳的 mysql 数据库中时间序列的最佳索引策略

c# - 使用 Windsor CaSTLe 从目录中检索 DLL

c# - 如何使用 async/await OnNext/OnError/OnCompleted 方法实现 IObserver?

Java Scanner - 将换行符读取到字符串中?

python - 在没有设置的情况下更快地获得两个列表的差异

java - 集成显卡上的 Java2D 绘图速度缓慢

c# - 从 C# 生成 JavaScript 的好的架构是什么?

c# - 在 WPF 中的 UserControl 中设置窗口所有者

c# - 从编译器的角度来看,字符串是怎样的?