Is using Lazy<T> bad for performance?

为君一笑 提交于 2021-02-07 05:28:25

问题


Recently I was having some issues with a singelton class that was lazy initializing a dictionary where a second thread would try to use it before it had actually been populated. So I implemented the variable initialization through the Lazy<T> class.

Here is my code:

private static Dictionary<string, string> GroupDefaults
{
    get { return mGroupDefaults.Value; }
}
private static Lazy<Dictionary<string, string>> mGroupDefaults =
    new Lazy<Dictionary<string,string>>(delegate
    {
        Dictionary<string, string> defaults = new Dictionary<string, string>();
        foreach (KeyValuePair<string, UnitGroup> groupDef in Groups)
            defaults.Add(groupDef.Key, groupDef.Value.First().Key);
        return defaults;
    });

This fixed the problem and now I am considering making this a regular practice of mine to use the Lazy<T> class anywhere I do lazy initialization to avoid any possible threading issues. So basically I would like to know if this is good/common practice? Or will it be detremental to performance or something?


回答1:


It's pretty hard to say without knowing what type of performance constraints you have, but in my experience, one-time initialization is rarely a bottleneck (since by definition it only occurs once.) Lazy<T> was written to provide you with this exact service, so I would recommend using it.




回答2:


From the documentation, I find the following:

If no delegate is passed in the Lazy constructor, the wrapped type is created by using Activator.CreateInstance when the value property is first accessed. If the type does not have a default constructor, a run-time exception is thrown.

Activator.CreateInstance is a method that is notoriously bad for performance. However, that doesn't seem to be a problem in your case, and at any rate, as dlev said, invoking the method once wouldn't be a problem. I haven't seen Lazy<T> used very often, but I do not see any reason not to use it in your case.




回答3:


If this is for a singleton, a static constructor might be what you want. Something like:

class MySingleton
{
    static MySingleton()
    {
         Instance().InitDict();
    }
}



回答4:


I think you may be using Lazy for not it's intended use. Lazy is to be used for situations where something has a large initialization cost, but there is a probable chance that it may not be used during the lifetime of the object.

If you always call GroupDefaults at least once per it's lifetime a better method would be to initialize GroupDefaults in a background thread at the start of the container's lifetime and hope that it is done before it is done initializing (I know there is a class for this but I need to dig in to the MSDN to find it)



来源:https://stackoverflow.com/questions/11236855/is-using-lazyt-bad-for-performance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!