C ,DO函数知道先前计算的函数值,或者必须重新计算它们

C++, do functions know previously computed function values or do they have to recompute them?

本文关键字:计算 函数 新计算 DO 或者      更新时间:2023-10-16

我有一个非常昂贵的功能,可以检查对象是否具有某个属性。然后,另一个功能将取决于对象是否具有属性,执行不同的操作。

如果我以前已经检查过该属性,是否会被第二个功能重新计算,还是知道?

我在想:

bool check_property(object){
    // very costly operations...
}
void do_something(object){
    if(check_property) {do thing}
    else {do different thing}
}

do_something中的if会重新计算check_property

编译器必须组合几个因素以避免重新计算该函数的结果:

  1. 编译器必须知道函数结果取决于哪个输入值。在通常的情况下,这些知识很难从代码中提取。在某些实现中,您可以使用编译器特定方式来帮助编译器,以将您的函数声明为"纯"或" const"(GCC函数属性)

  2. 编译器必须确保上述输入值没有更改,因为先前调用了同一函数。在某些特定情况下,这可能非常容易,但在通常的情况下也很困难。

  3. 编译器必须具有以前的计算的结果。通常,编译器不会故意"缓存"此类结果,以供将来的重复使用一些专用的存储空间。通常,仅当您在"近距离接近"中对同一函数进行多个呼叫时,通常才能实现优化,这意味着先前的结果很容易保留到下一个呼叫的那一刻。

因此,所讨论的优化肯定是可能的。但是,您应该期望在简单且非常局部的情况下看到它,例如以相同的 x值(在同一表达式中,在同一周期等)中连续多次调用sqrt(x)。但是,对于更复杂的功能,通常避免对相同昂贵的功能进行多个调用,或者可能是 emoize ,如果您认为它可以使您的代码受益。

,除非编译器可以证明check_property没有副作用,并且其依赖的所有数据都是相同的,则不允许删除呼叫;出于所有实际目的,除非您的功能正文在当前的TU中已知,否则它几乎是微不足道的,并且在同一函数中发生多个调用,请再次调用将再次执行其代码。我不知道有任何自动建立一个互vall缓存的编译器,因为它根本不是很容易的。

如果您需要缓存计算值,通常您必须自己做;请记住,这并不总是很琐碎 - 通常要解决的丑陋野兽是缓存无效的(我如何知道用于计算值的数据从我上次计算起来并没有变化?如何避免使用缓存大小失控了吗?)和多线程的问题(该代码会从多个线程调用吗?如果是这样,我必须同步对缓存的访问,可能会在无关线程之间添加耦合,并且在极端情况下,杀死了的效率缓存本身)。

回答您的问题,是的。它将重新运行。如果要确保每次致电do_something时都不会再次运行代码,请尝试在类中添加一个变量,以告诉您是否已经运行:

bool check_property(object){
// very costly operations...
return true;
}
void do_something(object,bool has_run){
if(has_run) {do thing}
else {do different thing}
}
void main() {
bool has_run = false;
has_run = check_property(object);
do_something(object,has_run);
}

当然有多种方法可以做到这一点,这可能不符合您的标准,但这是一种可能的方法!

我只是意识到这并不是C 的工作方式,因为与Java不同,所有内容都不在课堂上。相反,您可以将值作为参数传递给函数本身。因此,我已经编辑了我的代码。