c# vb:我们真的需要 System.Lazy 吗?

发布于 2024-11-02 18:24:20 字数 339 浏览 0 评论 0原文

我们真的需要 System.Lazy 吗?假设我的类库有 100 个静态类,每个静态类平均使用 100 个静态 System.Lazys = 10000 System.Lazys,当使用我的类库的程序启动时必须启动这些静态类吗?

我的意思是我们通常不只使用 1 个类库,比如说我们导入 15 个 .dll,每个 .dll 都有大量静态 System.Lazys.. 我很确定启动所有这些 System.Lazys 需要很长时间,更不用说它也会囤积大量内存(因为每个都有自己的 System.Func 让我们把它放在 50 个字节 = 500kb 内存中)

所以我想知道..最好只做“旧”方式(比如使用布尔值来跟踪某些内容是否已启动)

Do we really need System.Lazy? Let's say my class library have 100 static classes and each static class uses an average of 100 static System.Lazys = 10000 System.Lazys that have to be initiated when a program that uses my class library starts?

I mean we usually don't only use 1 class library, say we import 15 .dlls each of them have a ton of static System.Lazys.. I'm pretty sure its gonna take a long time initiating all those System.Lazys, not to mention its gonna hoard a ton of memory as well (since each have its own System.Func let's put it at 50 bytes each =500kb in memory)

So I was wondering.. is it best to just do it the "old" way (like using a boolean to keep track of whether something is initated)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷乱花海 2024-11-09 18:24:20

仅在以下情况下才应使用Lazy:1) 很有可能不需要该实例,并且 2) 启动实例的成本足够高,足以证明开销是合理的。

如果一个类中有 100 个静态惰性成员,那么几乎肯定你做错了。

You should only use Lazy if 1) there's a good chance the instance won't be needed, and 2) the cost of spinning up the instance is high enough to justify the overhead.

If you have 100 static lazy members in a class, you're almost certainly doing it wrong.

友欢 2024-11-09 18:24:20

正如其他人所说,如果您需要这种延迟初始化,您会遇到更大的问题。

但无论如何,只是为了展示您应该如何自己处理这个问题:在做出假设之前进行测量。

下面的程序(灵感来自 ayende) 测量创建和初始化仅分配新对象的 Lazy() 实例的开销。

我的机器上的输出:

Created 583599 objects in 00:00:01.0000117
Created 679939 objects in 00:00:01.0039926
Created 688751 objects in 00:00:01.0000013
Created 678244 objects in 00:00:01.0000018
Created 682506 objects in 00:00:01.0000018
Created and initialized 516400 lazy objects in 00:00:01.0000018
Created and initialized 526585 lazy objects in 00:00:01.0000049
Created and initialized 519425 lazy objects in 00:00:01.0000018
Created and initialized 514477 lazy objects in 00:00:01.0000022
Created and initialized 523544 lazy objects in 00:00:01.0005176
Performance loss: 21,5091944284387 %

不要从中得出一般性结论,因为性能问题很多时候都与当前情况非常具体。

但正如您所看到的,通过 Lazy 实例化对象的开销与简单地通过 new 分配对象相比,开销相对较小,因为 Lazy 应该通常在延迟实例化有用的情况下(即昂贵,并且构造的对象很可能实际上并不需要)

class Program
{
static void Main(string[] args)
    {
        var sequence = Enumerable.Range(1, 5);

        var q1 = from s in sequence
                 select GenerateSimpleObjects();

        var q2 = from s in sequence
                 select GenerateAndInitializeLazies();

        var m1 = q1.Average();
        var m2 = q2.Average();

        Console.WriteLine("Performance loss: {0} %", 100 - 100 * m2/m1);

    }

    static void GenerateSimpleObjects()
    {
        var sp = Stopwatch.StartNew();

        int i = 0;
        while (sp.ElapsedMilliseconds < 1000)
        {
            new object();
            i++;
        }
        sp.Stop();
        Console.WriteLine("Created {0} objects in {1}", i, sp.Elapsed);
    }


    static void GenerateAndInitializeLazies()
    {
        var sp = Stopwatch.StartNew();

        int i = 0;
        while (sp.ElapsedMilliseconds < 1000)
        {
            var l = new Lazy<object>(() => new object());
            var o = l.Value;
            i++;
        }
        sp.Stop();
        Console.WriteLine("Created and initialized {0} lazy objects in {1}", i, sp.Elapsed);
    }
}

As the others have said, you have much bigger problems if you need this kind of lazy initialization.

But anyway, just to show how you should be handling this question yourself: MEASURE before making assumptions.

The program below (inspired by ayende) measures the overhead of creating and initializing a Lazy() instance that simply allocates a new object.

output on my machine:

Created 583599 objects in 00:00:01.0000117
Created 679939 objects in 00:00:01.0039926
Created 688751 objects in 00:00:01.0000013
Created 678244 objects in 00:00:01.0000018
Created 682506 objects in 00:00:01.0000018
Created and initialized 516400 lazy objects in 00:00:01.0000018
Created and initialized 526585 lazy objects in 00:00:01.0000049
Created and initialized 519425 lazy objects in 00:00:01.0000018
Created and initialized 514477 lazy objects in 00:00:01.0000022
Created and initialized 523544 lazy objects in 00:00:01.0005176
Performance loss: 21,5091944284387 %

Don't draw general conclusions from this because performance problems are many times very specific to the situation at hand.

But as you can see, the overhead of instantiating an object via Lazy vs. simply allocating it through new is relatively small, given that Lazy should be typically in situations where delayed instantiation is useful (i.e. expensive, and the object constructed has a good chance of not being actually needed)

class Program
{
static void Main(string[] args)
    {
        var sequence = Enumerable.Range(1, 5);

        var q1 = from s in sequence
                 select GenerateSimpleObjects();

        var q2 = from s in sequence
                 select GenerateAndInitializeLazies();

        var m1 = q1.Average();
        var m2 = q2.Average();

        Console.WriteLine("Performance loss: {0} %", 100 - 100 * m2/m1);

    }

    static void GenerateSimpleObjects()
    {
        var sp = Stopwatch.StartNew();

        int i = 0;
        while (sp.ElapsedMilliseconds < 1000)
        {
            new object();
            i++;
        }
        sp.Stop();
        Console.WriteLine("Created {0} objects in {1}", i, sp.Elapsed);
    }


    static void GenerateAndInitializeLazies()
    {
        var sp = Stopwatch.StartNew();

        int i = 0;
        while (sp.ElapsedMilliseconds < 1000)
        {
            var l = new Lazy<object>(() => new object());
            var o = l.Value;
            i++;
        }
        sp.Stop();
        Console.WriteLine("Created and initialized {0} lazy objects in {1}", i, sp.Elapsed);
    }
}
忆离笙 2024-11-09 18:24:20

Lazy 旨在谨慎使用,在图中延迟加载对象有意义的情况下。也就是说,对于可能不需要但可能需要的对象,并且获取它们的成本很高。

为此,它们是一个很好的解决方案。

如果您知道您将使用所有对象,请不要使用Lazy

Lazy<T> is meant to be used sparingly, where it makes sense to lazy load objects in a graph. That is, for objects that are likely not needed, but may be, and if the cost for fetching them is high.

For that, they are a great solution.

If you know you will be using all of the objects, don't use Lazy<T>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文