【问题标题】:Problems with lazy initialization of singleton单例延迟初始化的问题
【发布时间】:2015-07-02 00:06:18
【问题描述】:

我想制作具有如下行为的单例类。

  1. 我的程序资源非常有限,所以在需要之前我不想创建单例实例。 (延迟初始化)
  2. 单例类非常庞大,因此初始化需要很长时间。
  3. 响应时间在此程序中很重要。(如游戏)

但如您所知,1 & 2 & 3 是相互冲突的。 在这种情况下,我必须选择其中之一(内存或性能)

程序有什么解决方案可以满足内存和性能要求吗?

【问题讨论】:

  • 最直接的答案似乎是:不要使用单例(除非你 100% 确定自己在做什么)。
  • 您在程序执行的某个时刻是否需要单例,或者程序可能不需要在给定的运行中使用它?如果是前者,那么你最好在开始时初始化它,因为内存和 CPU 会在某个时候受到打击,所以我认为隐藏它的最佳位置是在启动时而不是在程序执行的中途。

标签: c++ singleton


【解决方案1】:

“程序有什么解决方案可以满足内存和性能要求吗?”

无论如何都需要满足这些要求。为了确保单例类的惰性实例化,我建议使用 scott meyer 的单例实现来保证 here 中提到的惰性/线程安全初始化:

class Singleton {
public:
     static Singleton& Instance() {
          static Singleton theInstance;
          return theInstance;
     }
     delete Singleton(const Singleton&);
     delete Singleton& operator=(const Singleton&);
private:
     Singleton() {}

};

关于内存消耗,您必须以不同的方式对其进行优化。我实际上无法确定您可能在哪里缩小内存占用。到目前为止,您的问题没有提供足够的信息。


“但如你所知,1 & 2 & 3 是相互冲突的。在这种情况下,我必须选择其中之一(内存或性能)”

我看不到任何实际的冲突??第一次访问Singleton::Instance可能会有性能问题,但后续访问不会触发初始化,那又怎样?

【讨论】:

    【解决方案2】:

    很难说,因为你没有提供很多细节。你的资源在内存和磁盘上是否有限?单例类需要时间来初始化,因为它很大,还是因为它必须进行很多计算?长时间是多少?多少是巨大的?什么是有限的资源?

    如果你有磁盘空间并且读/写磁盘比较快, 如果您可以在程序初始化期间花一些时间, 你也许可以创建你的类并将其序列化到磁盘(并保留文件 锁定),然后在内存不足时从那里读取您的实例。或者在另一个线程中创建单例并在主线程中做一些其他的事情。

    【讨论】:

    • 这并不能真正回答问题。阅读Singleton,如果你甚至尝试在这里回答这样的问题。
    • 程序有什么解决方案可以满足内存和性能要求吗?
    • 有许多选项,实际上是正交处理的,与是否使用单例无关。
    • "程序有什么解决方案可以满足内存和性能要求吗?"这才是真正的问题。在游戏中,不能得到性能和资源优化使用是一个规律,需要妥协,所以这类问题确实很常见。对于这种特定情况,是否使用单例是一个很好的解决方案,我无法判断。你不能说你没有看到任何冲突。性能影响可能非常糟糕,以至于无法通过游戏认证。同样,在不知道具体细节的情况下,我无法确定,但这是所有游戏开发团队都会遭受的痛苦。
    • “有许多选项,实际上是正交处理的,并且与是否使用单例无关”完全同意,这就是为什么我的回答不是针对单例的使用。即使不使用单例,响应时间与资源有限的问题仍然存在。但同样,在不知道细节的情况下,真的很难说。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    相关资源
    最近更新 更多