在构造函数中返回一个新对象或初始化成员?

时间:2010-06-17 21:56:44

标签: c# performance initialization

我们有一个数据提供程序类,它返回数据库中每个聚合的存储库。

让我们考虑以下情况:

public class DataProvider {
    public IBookRepository Books { get { retun new BookRepository(); } }
    public IAuthorRepository Authors { get { retun new AuthorRepository(); } }
}

如您所见,每次调用会员时,我们都会返回给定对象的新实例:DataProvider.Books.DoBANANAS();

VS

public class DataProvider {
    public IBookRepository Books { get; }
    public IAuthorRepository Authors { get; }

    public DataProvider()
    {
        Books = new BookRepository();
        Authors = new AuthorRepository();
    }
}

调用`DataProvider.Books.BANANAS();现在减少CPU /内存的重量?

当我刚刚开始实现这两个版本时,他们惊人地工作了!

但我的经验告诉我Version 1 Sucks。然而,我有足够的时间来全面优化和实施最终产品。 (这是在研究小组工作的好处之一)

2 个答案:

答案 0 :(得分:3)

显示的实现在构造和管理对象的方式上有所不同。在第一个示例中,每次在DataProvider上调用属性时都会创建一个新的存储库。如果存储库保存任何状态(例如,已获取对象的缓存),则与第二个示例相比,您将获得非常不同的行为,因为每次都会将此状态重置为其默认状态。

从您说两个版本都工作的事实,我会冒险猜测存储库对象不保持状态,只是数据库调用的代理。在这种情况下,它可能没有太大的区别。

然而,这两种方法的性能和内存配置文件是非常不同的。虽然过早优化是一件坏事而且往往是浪费时间,但我不打算这样做,因为在每个属性调用上创建一个新的存储库显然可能是后来的性能问题,或者更糟糕的是如果你介绍的话,仍然难以追踪错误进入存储库。创建更少的对象最终会减少对垃圾收集器的压力,但除非您创建数百万个对象,否则它将是一个可以忽略不计的差异。

总之,第二个例子是未来更好的例子,我认为现在没有真正的问题。

答案 1 :(得分:2)

您的第一个示例每次都会创建一个XXXRepository对象的新实例,其中第二个示例返回一个已存在的句柄,因此第二个应该执行得更好并且使用更少的CPU,因为不需要分配新内存。

更大的问题是,除非存储库类完全是静态的,否则这两种情况会产生完全不同的结果。如果存储库类是某种类型的数据库接口,那么选项1不需要在选项2的情况下是线程安全的。