1

考虑以下代码(Julia)

bar(x) = for i = 1:9999 x+x*x-x+x end # Define the "bar" function
print("First try: "); @time bar(0.5)
print("Second try: "); @time bar(0.5)
bar(x) = for i = 1:9999 x+x*x-x+x end # Redefine the same "bar" function
print("Third try: "); @time bar(0.5)
print("Fourth try: "); @time bar(0.6)

输出是

First try: elapsed time: 0.002738996 seconds (88152 bytes allocated)
Second try: elapsed time: 3.827e-6 seconds (80 bytes allocated)
Third try: elapsed time: 0.002907554 seconds (88152 bytes allocated)
Fourth try: elapsed time: 2.395e-6 seconds (80 bytes allocated)

为什么第二次(和第四次)尝试比第一次(和第三次)尝试更快(并且占用更少的内存)?

4

2 回答 2

3

据我所知,Julia 有一个即时编译器。所以第一次(和第三次)运行正在编译代码(使用所需的分配),第二次(和第四次)运行只是运行先前编译的代码

于 2015-01-02T16:31:10.830 回答
3

只是为了扩展 Paul 的答案:加速的很大一部分来自 Julia 的类型推断和多次调度。假设您第一次使用浮点数评估函数:JIT(即时编译器)计算出参数的类型并编写适当的 LLVM 代码。如果您随后使用整数评估相同的函数,则会编译不同的 LLVM 代码。接下来调用该函数时,它将根据参数的类型分派不同的 LLVM 代码。这就是为什么在定义函数时编译通常没有意义的原因。

例如,您可以在此处阅读有关此内容的更多信息(文档中有大量对多次调度的引用!)

例如,考虑:

bar(x) = for i = 1:9999 x+x*x-x+x end

print("First try with floats: "); @time bar(0.5)
print("Second try with floats: "); @time bar(0.5)

print("First try with integers: "); @time bar(1)
print("Second try with integers: "); @time bar(1)

这使:

First try with floats: elapsed time: 0.005570773 seconds (102440 bytes allocated)
Second try with floats: elapsed time: 5.762e-6 seconds (80 bytes allocated)    
First try with integers: elapsed time: 0.003584026 seconds (86896 bytes allocated)    
Second try with integers: elapsed time: 6.402e-6 seconds (80 bytes allocated)
于 2015-01-05T01:22:02.320 回答