保留计时器集合(对象与指针)的最佳方法



我一直在尝试为 chrono 的high_performance_clock实现一个包装类。基本上有一个诊断母类,它保留了一个容器TaskTimers.到目前为止,我一直将它们作为std::vector<TaskTimer*>列表中的原始指针保留,但是阅读智能指针和指针与对象讨论时,我不确定该怎么想。似乎结果可能是赞成或反对的,这取决于实验。

在这种情况下,对于什么是"正确"的,是否有普遍共识? 我正在寻找性能而不是可读性。

诊断类允许程序员将计时器放置在代码的任何位置,以及启动、暂停和停止它们。可以通过name(std::string)id(int)访问它们。

std::unique_ptr<std::vector<std::shared_ptr<TaskTimer>>> m_TimerList;

诊断片段:

inline int AddTimer(const std::string& timerName, bool runImmediately = true) {
if (IsEnabled()) {
auto it = std::find_if(m_TimerList->begin(), m_TimerList->end(), [timerName](TaskTimer* obj) { return obj->GetName() == timerName; });
if (it != m_TimerList->end()) { return -1; } // exists
else {
std::shared_ptr<TaskTimer> t(new TaskTimer(timerName, m_NextID, m_Debug));
m_TimerList->push_back(t);
if (runImmediately) { _Start(t); }
return m_NextID++;
}
return -1;
}
return -2;
}
inline void Start(const int timerID) {
auto el = _GetFromID(timerID);
if (el != nullptr) { _Start(el); }
}
inline void Pause(const std::string& timerName) {
if (!IsEnabled()) { return; }
auto el = _GetFromName(timerName);
if (el != nullptr) { el->Pause(); }
}
inline std::shared_ptr<TaskTimer> _GetFromID(const int id) const {
const auto it = std::find_if(m_TimerList->begin(), m_TimerList->end(), [&id](std::shared_ptr<TaskTimer>& obj) {return obj->GetID() == id; });
if (it != m_TimerList->end()) { return (*it); }
return nullptr;
}
inline std::shared_ptr<TaskTimer> _GetFromName(const std::string& name) const {
const auto it = std::find_if(m_TimerList->begin(), m_TimerList->end(), [&name](std::shared_ptr<TaskTimer>& obj) {return obj->GetName() == name; });
if (it != m_TimerList->end()) { return (*it); }
return nullptr;
}
inline void _Start(std::shared_ptr<TaskTimer> t) {
if (!t->IsStarted()) {
t->Start();
m_StartedCount++;
}
else {
if (!t->IsRunning()) { t->Start(); }
else                 { t->Resume(); }
}
}

我想了解在对象/指针管理方面什么是"正确"选择背后的原因。我的TaskTimers集合是否像现在一样最适合性能? 有没有更好的方法可以在保留当前功能的同时做到这一点?

对于动态分配的对象,原始指针几乎总是错误的选择,因为它们不可避免地会导致内存泄漏和/或释放后使用错误。

因此,唯一真正的决定是智能指针与值语义;答案在很大程度上取决于TaskTimer 类的实现方式。

  • TaskTimer是"轻量级"或"POD"对象,非常便宜且易于复制吗? 如果是这样,那么只需按值保存TaskTimer对象(例如std::vector<TaskTimer>(很好。

  • OTOH,制作TaskTimer对象的副本是否计算成本高昂(甚至是编译时或运行时错误(? 如果是这样,那么智能指针就是要走的路,因为这种方法将允许TaskTimer对象的生存期比创建它们的范围的生存期更长。

相关内容

最新更新