通常我需要最小化运行频率非常高的代码中的对象分配。
当然,我可以使用普通的技术,如对象池,但有时我只想要本地包含的东西。
要尝试和实现这一目标,我想出了如下:避免重复分配没有变量/成员的操作对象
public static class Reusable<T> where T : new()
{
private static T _Internal;
private static Action<T> _ResetAction;
static Reusable()
{
_Internal = Activator.CreateInstance<T>();
}
public static void SetResetAction(Action<T> resetAction)
{
_ResetAction = resetAction;
}
public static T Get()
{
#if DEBUG
if (_ResetAction == null)
{
throw new InvalidOperationException("You must set the reset action first");
}
#endif
_ResetAction(_Internal);
return _Internal;
}
}
目前,用法是:
// In initialisation function somewhere
Reuseable<List<int>>.SetResetAction((l) => l.Clear());
....
// In loop
var list = Reuseable<List<int>>.Get();
// Do stuff with list
我想什么来改善,是一个事实,即整个东西不包含在一个地方(.SetResetAction
与它实际使用的地方是分开的)。
我想获得的代码类似下面:
// In loop
var list = Reuseable<List<int>>.Get((l) => l.Clear());
// Do stuff with list
这样做的问题是,我得到一个对象分配(它创建了一个Action<T>
)每一个循环。
是否有可能获得使用后我没有任何对象分配?
很明显,我可以创建一个ReuseableList<T>
这将有一个内置的Action
,但我想允许其他情况下,行动可能会有所不同。
我假设,我会仔细检查。 – 2012-02-02 16:31:05
你很对,它确实缓存了委托。 – 2012-02-02 16:42:55
@GeorgeDuckett:小心不要依赖于此;小的改变可以改变缓存的生成。例如,如果lambda在本地关闭,如果它关闭“this”,如果外部方法是通用的,等等,委托生成的工作方式会有所不同。 – 2012-02-02 17:12:55