C# 将列表设置为其本身是否会影响性能?
我有一个列表,如果尚未实例化,它可能为null,我希望在调用GetList()时能够返回现有列表或创建列表,然后返回。这看起来更干净:C# 将列表设置为其本身是否会影响性能?,c#,performance,list,C#,Performance,List,我有一个列表,如果尚未实例化,它可能为null,我希望在调用GetList()时能够返回现有列表或创建列表,然后返回。这看起来更干净: private List<object> m_objects; public List<object> GetList() { m_objects = m_objects ?? new List<object>(); return m_objects; } 私有列表m_对象; 公共列表GetList() {
private List<object> m_objects;
public List<object> GetList()
{
m_objects = m_objects ?? new List<object>();
return m_objects;
}
私有列表m_对象;
公共列表GetList()
{
m_对象=m_对象??新列表();
返回m_对象;
}
但是,将列表设置为其本身是否会影响性能,或者C#是否意识到这是不必要的
另一种选择是:
private List<object> m_objects;
public List<object> GetList()
{
if(m_objects != null)
{
return m_objects;
}
m_objects = new List<object>();
return m_objects;
}
私有列表m_对象;
公共列表GetList()
{
if(m_对象!=null)
{
返回m_对象;
}
m_objects=新列表();
返回m_对象;
}
显然不是世界末日,但我还是很好奇。使用:
private Lazy m_objects=new Lazy();
公共列表GetList()
{
返回m_objects.Value;
}
解决性能问题。在这里担心性能是过早的优化。您应该首先对其进行编码以使其正常工作,然后如果发现任何与性能相关的问题,请对其进行分析并进行优化。这是非常有效的:
private List<string> items;
public List<string> Items { get { return items ?? (items = new List<string>()); } }
私有列表项;
公共列表项{get{return Items???(Items=new List());}
注意??(items=
差异。如果它具有非空值,则在??
处为布尔短路,因此没有性能影响
如前所述,如果您想使用代码,那么是的,每次创建新元素时它都会造成性能影响。可能会有最小的性能影响,因为您基本上是将
m\u objects
中的引用分配给m\u objects
字段。这实际上只是复制一个64或32 bi您不会复制所有数据,只复制对对象实例的引用(或null)
对于您的代码,我认为只要您不担心多线程,使用??引号是非常整洁和充分的。如果您担心多线程,那么懒人建议@MichałKędrzyński建议的方法是更好的方法,因为您不需要对所有这些进行编程
唯一的例外情况是,由于UI限制,您需要确保自己位于WPF中的调度程序线程或Winforms中的UI线程上
编辑
请纠正我自己的回答,如果泛型类型无论如何都不了解线程安全(例如,列表不是线程安全的),那么使用Lazy是没有意义的。因为问题特别要求性能,这在调用
GetList()
时为您提供了最好的性能,而且它是线程安全的:
private readonly List<object> m_objects = new List<object>();
public List<object> GetList()
{
return m_objects;
}
private readonly List m_objects=new List();
公共列表GetList()
{
返回m_对象;
}
另一个使其线程安全的选项是使用
Lazy
。这会延迟new List()
,而代价是总是执行new Lazy()
,并在GetList()
方法中增加额外开销。或者简单地说:private readonly List m_objects=new List();public List GetList(){return m_objects;}
与任何性能问题一样,您当然可以简单地对其进行测试。尽管我严重怀疑这会有多大区别。对于初学者来说,如果我们不打算每次都使用对象,我们并不总是希望对象是新的。我甚至可以称此为惰性初始化。惰性做什么?至少包含的任何引用都是b作为一个更好的答案,IMHO。@BeytanKurt如果您想了解更多,您可以查看该类型的文档。在这里担心性能是非常过早的优化。@PeterSchneider,它在这里没有被禁用。我不希望它会显著地更贵;它不太可能有意义,但OP的代码是,在世界上在这种情况下,从一个注册表值到另一个注册表值执行多余的赋值,因此这是一个尽可能快的操作。我相信所有的选项都足够好,但我毫不怀疑这会更慢(以某种边际量)当然,但是考虑一下2个线程同时获得价值的情况。<代码>懒惰< /代码>确保它将是相同的值,而不是2个不同的列表。这就是“代码>懒惰< /代码>的情况。内部对象的线程安全性是另一个问题。o-例如,动态或懒惰更好。这实际上并不是回答所问的问题。不要认为该问题需要其他选择,它会询问特定的样式是否会导致过热。在添加“是的,确实”之后,这两种样式都会回答问题,并给出一个简单而聪明的选择。编辑后:否“每次都会创建对象”在OP的代码中,还是我遗漏了什么?引用被分配给它自己,除非分配被优化掉(这可能是OP所要求的)。这可能是最好的用法,只要不通过创建大量父类来创建大量m_对象。
。如果GetList()只针对父类的一小部分调用,这将创建大量空列表,并不必要地运行大量列表构造函数。很好,我一直在留下注释,因此自动对我的列表执行相同操作,而不是像通常那样进行编辑!哦,但感谢您指出这一点
private readonly List<object> m_objects = new List<object>();
public List<object> GetList()
{
return m_objects;
}