c# - 是否可以为 LINQ 使用自定义内存分配器?
问题描述
有没有办法为 LINQ 使用自定义内存分配器?
例如,当我打电话时:
someCollection.Where(x).SelectMany(y).ToList();
像ToList()
or这样的方法OrderBy()
总是会创建一个新数组,所以会发生很多 GC。使用自定义分配器,我总是可以使用相同的列表,每次都会被清除和重新填充。我知道重用缓冲区可能会导致重入问题。
背景是,我的应用程序是一个游戏,而 GC 意味着口吃。请不要告诉我“改用 C++”或“不要使用 LINQ”,我知道 :)
解决方案
(尽管您要求不要反对它,但我认为这个答案可以帮助社区)
LINQ 是建立在 CLR 之上的工具,因此它使用 CLR 分配器,并且无法更改。你可以稍微调整一下,例如配置是否应该将 GC 周期卸载到后台线程,但你不能再进一步了。
LINQ 的目的是简单地为某些类别的问题编写代码,牺牲选择每个构建块的实现的自由(这就是我们通常选择 LINQ 的原因)。
但是,根据具体情况,LINQ 可能不是您最好的朋友,因为它的设计选择可能会与您的选择不符。如果在分析您的代码之后,您发现您有严重的性能问题,您应该首先尝试确定您是否可以隔离某些 LINQ 方法中的瓶颈,并查看您是否可以通过扩展方法滚动您自己的实现。当然,当 yuo 是主要呼叫者时,此选项是可行的,除非您设法滚动一些IEnumerable
投诉。您需要非常幸运,因为您的实现应该遵守 LINQ 规则。特别是,由于您无法控制对象的操作方式,因此您无法在自己的代码中执行优化。关闭和延期执行对您不利。
否则,评论所建议的是唯一可行的选择:避免将 LINQ 用于该特定任务。
放弃 LINQ 的原因是它不是解决您需要的性能约束问题的正确工具。此外,正如评论中所述,(ab)使用 lambda 表达式显着增加了内存压力,因为创建了支持对象来实现闭包。
我们遇到了与您类似的性能问题,我们不得不重写某些慢速路径。在其他(罕见)情况下,预分配列表并通过 help.loading 加载结果AddRange
。
推荐阅读
- c# - 如何检查我的计算机上是否正在使用 C# 运行关闭进程?
- javascript - “TypeError: undefined is not an object (evalating '_expo.default.Font')]”在异步加载字体时遇到此错误
- c# - 如何在不获得锁定响应的情况下继续使用 TPM 签署数据?
- swift - 展开为时间戳时文档时间戳字段抛出错误
- terminal - zsh 不更新 vcs_info
- java - 如何从 json 数组中读取特定的 json 对象元素?
- angular - 如何在不订阅的情况下等待异步管道完成并在之后调用另一个函数
- aws-documentdb-mongoapi - 即使使用 maxTimeMS:0,DocumentDB 长时间运行的查询也会超时
- wagtail - Wagtail 多站点设置中的每个站点都有一个 404
- nginx - 处理海量数据API-PLATFORM