gpt4 book ai didi

C++ 使用 std::chrono 以一种很好的方式测量成员函数的执行

转载 作者:搜寻专家 更新时间:2023-10-31 01:27:46 24 4
gpt4 key购买 nike

我想优化我的应用程序,尤其是某些功能的执行速度。

假设有一个带有一些成员函数的类

class Test
{
public:
Test();
virtual ~Test();
int init(int arg1, double arg2);

private:
[...]

在我的构造函数中我调用了这些方法之一

Test::Test()
{
[...]
int value = init(1, 1.2);
}

如何在不破坏我的程序的情况下以一种干净利落的方式测量我的方法 init(...) 的执行时间?

目前我使用以下代码

Test::Test()
{
[...]
auto start = std::chrono::high_resolution_clock::now();

int value = init(1, 1.2);

auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> duration = stop - start;
std::cout << duration.count() * 1000 << "ms\n";
}

它按预期工作,但我认为它非常困惑,我想要一个“更干净”的解决方案。

有没有办法让某种函数接受一个成员函数和其他参数,就像这样

int value = countTime(function, arg1, arg2);

我不知道是否可以将 function() 的返回值传递给 countTime(),以免打断我的工作流程代码。

编辑:这是我的 TimeMeasure 类

namespace tools 
{
class TimeMeasure
{
public:
TimeMeasure()
{
m_start = std::chrono::high_resolution_clock::now();
}

virtual ~TimeMeasure()
{
m_stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> duration = m_stop - m_start;
std::cout << duration.count() << "ms\n";
}

public:
typedef std::chrono::time_point<std::chrono::high_resolution_clock> HighResClock;

private:
HighResClock m_start;
HighResClock m_stop;
};

template <typename T, typename F, typename... Args>
auto measure(T *t, F &&fn, Args... args)
{
tools::TimeMeasure timeMeasure;
return (t->*fn)(std::forward<Args>(args)...);
}
}

在我的构造函数 Test() 中,我以这种方式使用函数 measure

Test()
{
[...]
tools::measure(this, Test::init, filepath);
}

int init(const std::string& filepath) const 在这里将一个字符串带到一个文件中。所以就我而言,这只是一个论点

不幸的是,我得到一个invalid use of non-static member function 'int init(const string&) const'错误

我想知道构造函数是否不是成员函数。那么,为什么会出现此错误?

编辑 2:

根据 OznOg 的回答,我只是忘了提交指向我的函数的指针。

所以这才是正确的函数调用

tools::measure(this, &Test::init, filepath);

最佳答案

你可以创建一个类:

struct MeasureTime {
MeasureTime() : _start(std::chrono::high_resolution_clock::now()) {}

~MeasureTime() {
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> duration = stop - _start;
std::cout << duration.count() * 1000 << "ms\n";
}
private:
std::chrono::time_point<std::chrono::high_resolution_clock> _start;
};

并在您的代码中简单地使用它:

Test::Test()
{
MeasureTime mt;
[...]
{ //or even this for just the init call
MeasureTime mt2;
int value = init(1, 1.2);
}
}

恕我直言,它比你提议的要少干扰。

如果你真的想要一个函数,你可以尝试像这样的包装器:

template <class T, class F, class... Args>
auto MeasureTimeFn(T *t, F &&fn, Args&&... args) {
MeasureTime timer;
return (t->*fn)(std::forward<Args>(args)...);
}

然后这样调用它:

int value = MeasureTimeFn(this, &Test::init, 1, 1.2);

但不确定它是否真的好得多。

你可以尝试用宏隐藏东西:

#define MEASURE(f, ...) \
MeasureTimeFn(this, &std::remove_reference_t<decltype(*this)>::f, __VA_ARGS__)

这样就可以写

int value = MEASURE(init, 1, 1.2);

什么很像你要求的,但只在成员函数内部工作,成员函数(非静态)。

无论如何,这可能是一个不错的起点。

* 编辑*如果你可以修改你类的继承,你可以尝试

template<class T>
struct MeasureTool {
template <class F, class... Args>
auto measure(F &&fn, Args&&... args) {
tools::TimeMeasure timeMeasure;
return (static_cast<T*>(this)->*fn)(std::forward<Args>(args)...);
}
};

class Test : public MeasureTool<Test>
{
public:
Test();
virtual ~Test() {}
int init(const std::string &filepath) { _path = filepath; return 0; }
const auto &getPath() const { return _path; }
private:
std::string _path;

};

Test::Test()
{
std::string filepath("/some/where");
int value = measure(&Test::init, filepath);
measure(&Test::getPath);
}

而且,这一次,似乎符合您的第一个要求(但非常麻烦...)

现在,一切都在你的手中:)

关于C++ 使用 std::chrono 以一种很好的方式测量成员函数的执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52905915/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com