我有一个使用函数引用的类:
double u( const double& x, const double& y )
{
return x * y;
}
class equation
{
equation( double (&in_u)(const double&, const double&) );
//...
protected:
double (&u)(const double&, const double&);
}
在典型运行期间,此函数将被称为108次。
类进入库,函数u
由库的用户定义。所以我不能在类中定义函数。
我读过这个:
(标准::函数
)缺点是在被调用时引入一些(非常小的)开销(因此在性能非常关键的情况下,这可能是一个问题,但在大多数情况下不应该)
有没有更有效的方法将函数< code>u传递给类< code>equation?这算不算“性能非常关键的情况”?
编辑
似乎有点混乱。为了清楚起见,函数u
在可执行文件的编译时是已知的,但在库的编译时是未知的。在运行时获取函数是我将在库的更高版本中考虑的功能,但现在不行。
使用模板参数:
struct u {
double operator()(const double& x, const double& y) { return x * y; }
};
template <typename Function>
class equation {
equation();
//...
double using_the_function(double x, double y) {
//...
auto res = f(x, y);
//...
return res;
}
private:
Function f;
};
如果您不需要修改函数的参数,在函数中,最好通过值传递(在内置类型的情况下,这很可能是将加载到CPU寄存器中的值或已经加载的值)。
struct u {
double operator()(double x, double y) { return x * y; }
};
这最有可能在using_the_function
方法中内联u
。在这种情况下,编译器无法执行此操作,因为函数指针可以指向任何函数。
如果需要支持许多不同的函数和/或类,那么如果代码膨胀,这种方法可能会出现很大的问题。
假设该函数在编译时未知,因此您不会比函数指针/引用更快。
std::function
的优点是它允许您使用仿函数、成员函数指针或lambda表达式。但是有一些开销。
正如一条评论所提到的,我会替换常数双
下面是一个使用
std::function
的例子:
#include <iostream>
#include <functional>
#include <math.h>
double multiply(double x, double y) { return x * y; }
double add(double x, double y) { return x + y; }
class equation
{
public:
using ComputeFunction_t = std::function<double(double, double)>;
template <typename FunctionPtr>
equation(FunctionPtr pfn)
: computeFunction_m(pfn)
{ }
void compute(double d1, double d2)
{
printf("(%f, %f) => %f\n", d1, d2, computeFunction_m(d1, d2));
}
protected:
ComputeFunction_t computeFunction_m;
};
int main() {
equation prod(multiply);
prod.compute(10, 20); // print 200
equation sum(add);
sum.compute(10, 20); // print 30
equation hypotenuse([](double x, double y){ return sqrt(x*x + y*y); });
hypotenuse.compute(3, 4); // print 5
struct FooFunctor
{
FooFunctor(double d = 1.0) : scale_m(d) {}
double operator()(double x, double y) { return scale_m * (x + y); }
private:
double scale_m;
};
equation fooadder(FooFunctor{});
fooadder.compute(10, 20); // print 30
equation fooadder10(FooFunctor{10.0});
fooadder10.compute(10, 20);
struct BarFunctor
{
BarFunctor(double d = 1.0) : scale_m(d) {}
double scaledAdd(double x, double y) { return scale_m * (x + y); }
private:
double scale_m;
};
BarFunctor bar(100.0);
std::function<double(double,double)> barf = std::bind(&BarFunctor::scaledAdd, &bar, std::placeholders::_1, std::placeholders::_2);
equation barfadder(barf);
barfadder.compute(10, 20); // print 3000
return 0;
}
但是,同样,这种灵活性的增加确实需要很少的运行时成本。它是否值得取决于应用程序。我可能会先倾向于通用性和灵活的接口,然后再进行剖析,看看这对于实践中使用的各种功能是否是一个真正的问题。
如果您可以将解算器设置为只包含头的库,那么当用户在代码中提供内联函数时,您可能会获得更好的性能。例如:
template <typename ComputeFunction>
class Equation
{
public:
Equation(ComputeFunction fn)
: computeFunction_m(fn)
{ }
void compute(double d1, double d2)
{
printf("(%f, %f) => %f\n", d1, d2, computeFunction_m(d1, d2));
}
protected:
ComputeFunction computeFunction_m;
};
template <typename ComputeFunction>
auto make_equation(ComputeFunction &&fn)
{
return Equation<ComputeFunction>(fn);
}
< code>Equation
类的实例化现在可以完全内联函数的执行。给定< code>make_equation函数,调用是非常相似的(上面的实现假设C 14,但是C 11版本没有太大的不同):
auto fooadder2 = make_equation(FooFunctor{});
fooadder2.compute(10, 20);
auto hypot2 = make_equation([](double x, double y){ return sqrt(x*x + y*y); });
hypot2.compute(3, 4);
通过完全优化,您可能只会在编译后的代码中找到对printf
的调用以及计算结果。
一个函数指针(或者引用,在实现层几乎是一样的)就可以了。
现代CPU非常擅长分支预测,在第一对调用之后,CPU会意识到这个“间接”调用总是指向同一个位置,并使用推测执行来保持管道充满。
但是,仍然不会有跨越函数边界的优化。没有内联,没有自动矢量化。
如果此函数被调用108次,则可能有大量函数处于参数变化的非常紧密的循环中。在这种情况下,我建议更改函数原型以接受参数值数组并输出结果数组。然后在函数中有一个循环,编译器可以在其中执行优化,如展开和自动矢量化。
(这是通过减少跨边界的调用次数来处理互操作成本的一般原则的特定情况)
如果无法做到这一点,请按值传递参数。正如其他人所说,对于浮点变量,这比 const 引用最有效。可能效率要高得多,因为大多数调用约定将使用浮点寄存器(通常是SSE寄存器,在现代英特尔架构上,在此之前它们使用x87堆栈),它们已准备好立即执行计算。为了通过引用传递而将值溢出到RAM是非常昂贵的,当函数内联时,然后逐个引用传递被优化,但这在这里不会发生。不过,这仍然不如传递整个数组好。
目前,我得到了以下函数,该函数遍历Pandas DataFrame()列并创建一个计数: 我有许多参数要分配给/调用函数——目前,我正在做以下工作: 这样做效果很好,但我想知道是否有更实用/有效的方法可以达到同样的效果。 我正在考虑将变量名添加到列表中,例如、、、等,并形成某种循环——如果这样做可行的话。。。 因此,也许有点像: 或者,有没有使用熊猫的方法?
问题内容: 我可以通过以下代码在函数本身内部访问python函数的属性: 但是,如果以上函数是编写其他代码的模板,例如,我必须编写: 有没有类似于类方法中参数的“指针”,所以我可以编写这样的代码? 我进行搜索,发现有人说可以使用该类来解决此问题,但是重新定义所有现有功能可能会很麻烦。有什么建议? 问题答案: 函数没有通用的方式引用自身。考虑改用装饰器。如果您想要的只是打印有关可以通过装饰器轻松完成
Java匿名类只能从周围的方法访问变量,如果该变量是,因此内部类不能写入该变量。为了捕获由封闭类型创建的对象,我创建了一个单元素数组作为引用: ...标准Java运行时中是否存在这样的类? 我查看了,这不是一回事。这些都是不可变的,唯一的实现是针对弱/幻影引用的。
问题内容: 我有一组层次结构的数据,我想从Firebase检索信息。以下是我的数据的外观: 但是,我的问题是这样的:在查看数据的结构时,当我想抓取或时,必须执行以下代码: 现在,这遍历了每个参加者的孩子,并逐个获取名称和对象ID。函数完成后,我将每个值存储到字典中。这样做后,该函数将被多次调用,并且可能会非常慢,尤其是在多次访问数据库或从数据库访问数据库时。有没有更有效的方法可以做到这一点?我试图
比较函数是一个函数,它接受两个参数a和b,并返回一个描述其顺序的整数。如果a小于b,则结果为负整数。如果a大于b,则结果为某个正整数。否则,a和b相等,结果为零。 此函数通常用于参数化来自标准库的排序和搜索算法。 实现字符的比较功能相当容易;只需减去参数: 这是因为通常假设两个字符之间的差适合一个整数。(注意,此假设不适用于的系统) 这种技巧无法用于比较整数,因为两个整数之间的差通常不适合一个整数
考虑以下几点: 每秒最多可有100个并发请求的web应用程序 当前每个传入请求都向endpoint发出http请求以获取某些数据(最多需要5秒) 我只想发出一次http请求,也就是说,我不想对同一个endpoint进行并发调用,因为它将返回相同的数据 这个想法是,只有第一个请求才会进行http调用以获取数据 而此呼叫是“飞行”,随后的请求将不会发出相同的呼叫,而是“等待”第一个飞行请求完成。 当对