【发布时间】:2021-04-24 22:10:21
【问题描述】:
说明
你好, 我想创建一个可以执行任何类型函数的函数,在其执行结束时指示它所花费的时间。 被调用的函数可以有返回值,也可以没有返回值,0个或多个任意类型的参数。
调用函数必须打印如下内容:
Running "myFunction" .....
Done ! (5210ms)
基本上我想创建一个函数,通过在调用前后添加代码来调用作为参数传递的任何类型的函数。
我做了什么
现在我是这样做的。
调用函数:
template <typename T>
T callFunctionPrintTime(std::string fnName, std::function<T()> fn) {
std::cout << ">> Running " << fnName << " ... " << std::endl;
auto t1 = std::chrono::high_resolution_clock::now();
//Call to the target function
T retVal = fn();
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
std::cout << "Done ! (" << duration << " ms)" << std::endl;
return retVal;
}
主要
int main()
{
//Store the function to call
std::function<unsigned long()> fn = []() {
return myFunction(15, 10000);
};
//Use of the function we are interested in
auto i = callFunctionPrintTime("myFunction", fn);
//The return value of myFunction can be used in the rest of the program.
std::cout << "i: " << i << std::endl;
}
我的函数
这个函数无所谓,什么都可以。
这里我们在给定的最大时间或最大循环次数内执行一个while循环,并检索执行的循环次数。
unsigned long myFunction(long maxMs, unsigned long maxI) {
unsigned long i = 0;
auto tStart = std::chrono::high_resolution_clock::now();
while (maxMs > (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - tStart).count()) &&
maxI > i) {
i++;
}
return i;
}
问题
您最好的方法是什么?我对我的代码不满意。
我不确定我是否使用正确的方法通过参数传递任何类型的函数。
此外,通过使用 lambda 表达式来存储我的函数,我无法检索被调用函数的名称。所以我必须通过参数传递它的名字。
【问题讨论】:
-
如果代码已经按预期工作,Code Review 可能更合适。但是,请确保 red 在询问之前阅读了他们的帮助中心
-
函数名称在运行时不可访问。你需要求助于宏巫术或类似你写的东西。你的代码看起来不错
-
该代码看起来像我见过的所有“功能测量”代码。您可以使用一些可变模板恶作剧来避免 lambda 包装器,但这只会使其不那么通用且难以维护。
-
没有理由将一个限制为
std::function。相反,可调用对象可以是任何东西。然后,没有理由将自己限制在没有参数的函数上。模板可以为参数使用可变参数包,将其转发给函数。最后,返回void的函数不会像这样工作,因此应该使用在自动范围内构造的辅助对象来完成计时,模板只不过是实例化辅助对象,然后是return <call>,使用在助手的构造函数和析构函数中完成的所有工作。结束。 -
@zkoza 这侵入了被调用的函数,它可能无法编辑,并且 不应该 被编辑只是为了进行基准测试/测试/无论如何。在调用方测量时间是正确的。我承认这是对 RAII 的巧妙使用!