Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将列表设置为其本身是否会影响性能?_C#_Performance_List - Fatal编程技术网

C# 将列表设置为其本身是否会影响性能?

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() {

我有一个列表,如果尚未实例化,它可能为null,我希望在调用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;
}