下面的代码通过指数慢的算法计算斐波那契数:
#include <cstdlib>
#include <iostream>
#define DEBUG(var) { std::cout << #var << ": " << (var) << std::endl; }
constexpr auto fib(const size_t n) -> long long
{
return n < 2 ? 1: fib(n - 1) + fib(n - 2);
}
int main(int argc, char *argv[])
{
const long long fib91 = fib(91);
DEBUG( fib91 );
DEBUG( fib(45) );
return EXIT_SUCCESS;
}
我在运行时计算第45个斐波那契数,在编译时计算第91个。
有趣的事实是,GCC4.9编译代码并在几分之一秒内计算出fib91
,但吐出fib(45)
需要一段时间。
以上是否意味着GCC会生成fib
函数的两个编译版本,其中一个是快的,另一个是指数级慢的?
问题不是编译器如何优化fib(91)
计算(是的!它确实使用了某种记忆),而是如果它知道如何优化fib
函数,为什么它不对fib(45)
做同样的操作呢?并且,fib
函数有两个单独的编译吗?一个慢一个快?
GCC可能正在记忆constexpr
函数(启用fib(n)
)的JADEN(n)计算)。编译器这样做是安全的,因为constexpr
函数是纯函数的。
将(n)“编译器算法”(使用memoization)与(?n)运行时算法(其中?是黄金比例)进行比较,突然之间,编译器的速度快得多就变得非常有意义了。
从cppreference上的constexpr
页面(着重号为后加):
constexpr auto compute_fib(const size_t n) -> long long
{
return n < 2 ? n : compute_fib(n - 1) + compute_fib(n - 2);
}
template <std::size_t N>
struct fib
{
static_assert(N >= 0, "N must be nonnegative.");
static const long long value = compute_fib(N);
};
在代码的其余部分中,您可以访问fib<45>::value
或fib<91>::value
,并保证在编译时对它们进行计算。
问题内容: 我听说在某些情况下,由于JIT优化,Java程序或Java程序的某些部分比C ++(或其他预编译的代码)中的“相同”代码执行得更快。这是由于编译器能够确定某些变量的范围,避免某些条件并在运行时提取类似的技巧。 您能否举一个(或更佳的)例子,在哪里适用?也许概述了编译器能够优化字节码的确切条件,超出了预编译代码的范围? 注意: 此问题 不是 关于将Java与C ++进行比较。关于JIT编
发生在运行时,因为编译器不能在决定执行哪个函数,但为什么编译器不能在编译时决定呢? 产出: 狗在吃...
例如如下代码: SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); Date date = sdf.parse("abcd"); 这段代码会抛出ParseException,而它是编译时异常,为什么编译阶段不报错,运行时报错?
这两个类路径能完全不同吗?
问题内容: 何时加载静态变量,运行时或编译时?有人可以解释一下吗? 我非常感谢您的帮助。 谢谢。 问题答案: 它们在运行时加载。 静态表示:该变量属于该类,而不属于该类的实例。因此,每个静态变量只有一个值,如果您有该类的n个实例,则没有n个值。
问题内容: 专业人士使用这两种方式的缺点是什么? 我实际上在Netbeans的“项目属性”>“ Java应用程序的库”中看到了它。我们有两个选项卡,一个用于编译时间库和运行时库,看起来我们可以将一个库添加到彼此独立的一个库中 问题答案: “库属性”对话框的用户界面和术语非常混乱。 该对话框上的“帮助”按钮将为您提供一些信息。 编译时库列表可以是运行时库列表的子集。 考虑这种情况… 您具有从库“ w