我一直在尝试为chrono的high_performance_clock
实现包装类。基本上,有一个Diagnostics母类,其中包含TaskTimers
的容器。到目前为止,我一直将它们作为原始指针保存在std::vector<TaskTimer*>
列表中,但是在阅读智能指针以及指针与对象的讨论时,我不确定该怎么想。视实验而定,结果似乎是有利还是不利。
在这种情况下,对于什么是“正确的”是否有普遍共识? 我在寻找性能而不是可读性。
Diagnostics类允许程序员将计时器放置在代码的任何位置,以及启动,暂停和停止计时器。可以通过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
集合现在是否最适合性能?在保留当前功能的同时,还有更好的方法吗?
答案 0 :(得分:1)
对于动态分配的对象,原始指针几乎总是错误的选择,因为它们不可避免地导致内存泄漏和/或释放后使用错误。
因此,唯一真正的决定是智能指针与价值语义;答案将很大程度上取决于TaskTimer类的实现方式。
TaskTimer
是“便宜”或“ POD”的对象,它非常便宜且易于复制吗?如果是这样,那么只需按值保存TaskTimer
个对象(例如std::vector<TaskTimer>
)即可。
OTOH,复制TaskTimer
对象的副本在计算上是否昂贵(甚至是编译时或运行时错误)?如果是这样,那么智能指针便是可行的方法,因为这种方法将使您的TaskTimer
对象的生存期比在其创建范围内的生存期更长。