是否可以为LINQ使用自定义内存分配器?

时间:2019-02-01 21:50:09

标签: c# .net linq memory-management

是否可以使用LINQ的自定义内存分配器?

例如,当我打电话时:

import os
import time

file_path = r"C:\Users\WCS\Desktop\item.txt"
cTime=0
time_limit = 5

while cTime<time_limit:

    if os.path.exists(file_path)==False:
        cTime=cTime+1
        time.sleep(1)

    else:
        pass

if cTime==5:
    responce="Time's Up"
else:        
    responce='Found'

print(responce)

someCollection.Where(x).SelectMany(y).ToList(); ToList()之类的方法将始终创建一个新数组,因此将发生大量GC。 使用自定义分配器,我总是可以使用相同的List,该List每次都会被清除并重新填充。 Iam意识到重用缓冲区可能会导致重入问题。

背景是,我的应用程序是游戏,GC意味着结巴。 请不要告诉我“改用C ++”或“不要使用LINQ”,我知道:)

1 个答案:

答案 0 :(得分:1)

(尽管您不希望对此提出建议,但我认为这个答案可能会对社区有所帮助)

LINQ是在CLR之上构建的功能,因此它使用CLR分配器,并且不能更改。 您可以对其进行一些微调,例如配置是否应将GC周期卸载到后台线程,但是您无法进行进一步的操作。

LINQ的目的是简单地为某些类的问题编写代码,以牺牲选择每个构建基块的实现的自由(这就是我们通常选择LINQ的原因)。

但是,根据情况,LINQ可能不是您最好的朋友,因为它的设计选择可能与您的选择不符。 如果在对代码进行性能分析后确定自己存在严重的性能问题,则应首先尝试确定是否可以隔离某些LINQ方法中的瓶颈,并查看是否可以通过扩展方法来扩展自己的实现。 当然,如果您是主要呼叫者,则此选项是可行的,除非您设法解决IEnumerable投诉。您需要非常幸运,因为您的实现应遵守LINQ规则。特别是,由于您无法控制对象的操作方式,因此无法执行自己的代码中的优化。 关闭和延期执行对您不利。

否则,注释中建议的是唯一可行的选择:避免对特定任务使用LINQ。

之所以放弃LINQ,是因为它不是解决所需性能约束问题的正确工具。 此外,如评论中所述,lambda表达式的(ab)使用显着增加了内存压力,因为创建了用于实现闭包的后备对象。

我们遇到了与您类似的性能问题,我们不得不重写某些慢速路径。在其他(很少)情况下,通过AddRange预分配列表并加载结果会有所帮助。