使用私有 class 数据模式的成本是多少?
What's the cost of using private class data pattern?
我曾经将其作为库中的 TimeUnit
声明:
解决方案1:
typedef boost::posix::ptime TimeUnit;
TimeUnit createTimeUnit( int hours, int minutes );
std::string toString( const TimeUnit& timeUnit );
假设我想将其移动到更面向对象的东西:
解决方案2:
class TimeUnit : public boost::posix::ptime
{
public:
TimeUnit( int hours, int minutes );
std::string toString() const;
};
现在,假设我不希望使用这个 class 的库直接依赖于 boost,所以我想使用私有 class 数据模式来删除任何 boost来自我的头文件的引用:
解决方案3:
class TimeUnitPrivate;
class TimeUnit
{
public:
TimeUnit( int hours, int minutes );
~TimeUnit();
std::string toString() const;
public:
TimeUnitPrivate* m_data;
};
TimeUnitPrivate
与 Solution2 的 TimeUnit
大致相同,新的 TimeUnit
只是:
TimeUnit::TimeUnit( int hours, int minutes ) :
m_data( hours, minutes )
{}
TimeUnit::~TimeUnit()
{
delete m_data;
}
std::string TimeUnit::toString()
{
return m_data->toString();
}
Solution3 非常聪明,我肯定会节省编译时间 + 限制 boost 依赖项。
但我想知道每个解决方案的成本是多少:
- 内存使用。 TimeUnit 对象的三种解决方案是否需要相同数量的字节存储在内存中?如果不是,哪个最好(我想是 Solution1)
- 性能: 当然,Solution3 的
toString()
会比 Solution2 慢(因为函数不能内联,最后需要额外的函数调用) .这没什么大不了的。但我想知道对象 creation/destruction 是否会变慢......这三个解决方案将如何根据对象 creation/destruction 的性能进行排序?
前两个解决方案在内存使用和性能方面完全相同。一个只是比另一个更 object-y,纯粹是偏好问题。
handle-body/pimpl 习语解决方案将占用更多内存(按指针的大小)并且速度较慢(每次调用的额外间接,创建时的额外分配)。慢多少?你得抓紧时间。与编译时间的加速和依赖性的减少相比,额外的内存使用和性能损失是否对您造成伤害?完全取决于您的项目正在做什么。对于某些应用程序,这种规模的性能丝毫不重要,因此加速编译当然值得。对于其他应用程序,这完全是不可能的。没有通用的答案。
我曾经将其作为库中的 TimeUnit
声明:
解决方案1:
typedef boost::posix::ptime TimeUnit;
TimeUnit createTimeUnit( int hours, int minutes );
std::string toString( const TimeUnit& timeUnit );
假设我想将其移动到更面向对象的东西:
解决方案2:
class TimeUnit : public boost::posix::ptime
{
public:
TimeUnit( int hours, int minutes );
std::string toString() const;
};
现在,假设我不希望使用这个 class 的库直接依赖于 boost,所以我想使用私有 class 数据模式来删除任何 boost来自我的头文件的引用:
解决方案3:
class TimeUnitPrivate;
class TimeUnit
{
public:
TimeUnit( int hours, int minutes );
~TimeUnit();
std::string toString() const;
public:
TimeUnitPrivate* m_data;
};
TimeUnitPrivate
与 Solution2 的 TimeUnit
大致相同,新的 TimeUnit
只是:
TimeUnit::TimeUnit( int hours, int minutes ) :
m_data( hours, minutes )
{}
TimeUnit::~TimeUnit()
{
delete m_data;
}
std::string TimeUnit::toString()
{
return m_data->toString();
}
Solution3 非常聪明,我肯定会节省编译时间 + 限制 boost 依赖项。
但我想知道每个解决方案的成本是多少:
- 内存使用。 TimeUnit 对象的三种解决方案是否需要相同数量的字节存储在内存中?如果不是,哪个最好(我想是 Solution1)
- 性能: 当然,Solution3 的
toString()
会比 Solution2 慢(因为函数不能内联,最后需要额外的函数调用) .这没什么大不了的。但我想知道对象 creation/destruction 是否会变慢......这三个解决方案将如何根据对象 creation/destruction 的性能进行排序?
前两个解决方案在内存使用和性能方面完全相同。一个只是比另一个更 object-y,纯粹是偏好问题。
handle-body/pimpl 习语解决方案将占用更多内存(按指针的大小)并且速度较慢(每次调用的额外间接,创建时的额外分配)。慢多少?你得抓紧时间。与编译时间的加速和依赖性的减少相比,额外的内存使用和性能损失是否对您造成伤害?完全取决于您的项目正在做什么。对于某些应用程序,这种规模的性能丝毫不重要,因此加速编译当然值得。对于其他应用程序,这完全是不可能的。没有通用的答案。