在全局变量上行动比传递它们更快? [朱莉娅琅]

时间:2016-06-08 12:07:45

标签: performance parameter-passing global julia

我刚学完朱莉娅(最重要的是表演提示!)。我意识到使用全局变量会使代码变慢。对此的反措施是将尽可能多的变量传递给函数的参数。因此我做了以下测试:

x = 10.5  #these are globals
y = 10.5

function bench1()  #acts on global
  z = 0.0
  for i in 1:100
    z += x^y
  end
  return z
end

function bench2(x, y)
  z = 0.0
  for i in 1:100
    z += x^y
  end
  return z
end

function bench3(x::Float64, y::Float64) #acts on arguments
  z::Float64 = 0.0
  for i in 1:100
    z += x^y
  end
  return z
end

@time [bench1() for j in 1:100]
@time [bench2(x,y) for j in 1:100]
@time [bench3(x,y) for j in 1:100]

我必须承认结果非常出乎意料,并且与我所读到的内容不一致。 结果:

0.001623 seconds (20.00 k allocations: 313.375 KB)
0.003628 seconds (2.00 k allocations: 96.371 KB)
0.002633 seconds (252 allocations: 10.469 KB)

平均结果是第一个直接作用于全局变量的函数总是比最后一个具有所有正确声明并且不直接作用的函数快2倍。关于全局变量。有人可以向我解释原因吗?

2 个答案:

答案 0 :(得分:8)

还有一个问题是以下内容仍然在全球范围内:

@time

function runbench(N) x = 3.0 y = 4.0 @time [bench1() for j in 1:N] @time [bench2(x,y) for j in 1:N] @time [bench3(x,y) for j in 1:N] end 报告的大量分配中可以看出。

将所有这些包裹在一个函数中:

runbench(1)

使用runbench(10^5)预热,然后1.425985 seconds (20.00 M allocations: 305.939 MB, 9.93% gc time) 0.061171 seconds (2 allocations: 781.313 KB) 0.062037 seconds (2 allocations: 781.313 KB) 我得到

bench3

在情况2和3中分配的总内存是8 ^ 5乘以8字节,正如预期的那样。

道德是几乎忽略实际的时间,只看一下内存分配,这是有关类型稳定性的信息。

编辑:$ mkdir a $ printf "package a;\npublic class a {\npublic static void main(String[] argv) {\nSystem.out.println(\"we're here\");\n}\n}" > a/a.java $ javac -s a a/a.java $ java -cp . a.a we're here 是Julia中的“反模式”(即未使用的编码风格) - 您不应仅仅为了尝试修复类型不稳定而注释类型;这不是朱莉娅的注释类型。

答案 1 :(得分:6)

我猜这主要是因为编译时间。如果我将“主要”代码更改为

N = 10^2
println("N = $N") 

println("bench1")
@time [bench1() for j in 1:N]
@time [bench1() for j in 1:N]

println("bench2")
@time [bench2(x,y) for j in 1:N]
@time [bench2(x,y) for j in 1:N]

它给出了

N = 100
bench1
  0.004219 seconds (21.46 k allocations: 376.536 KB)
  0.001792 seconds (20.30 k allocations: 322.781 KB)
bench2
  0.006218 seconds (2.29 k allocations: 105.840 KB)
  0.000914 seconds (402 allocations: 11.844 KB)

因此,在第二次测量中,bench1()bench2()慢〜2倍。 (我省略了bench3()因为它给出了与bench2()相同的结果。)如果我们将N增加到10 ^ 5,编译时间与计算时间相比可以忽略不计,所以我们可以看到即使在第一次测量中,bench2()的预期加速也是如此。

N = 100000
bench1
  1.767392 seconds (20.70 M allocations: 321.219 MB, 8.25% gc time)
  1.720564 seconds (20.70 M allocations: 321.166 MB, 6.26% gc time)
bench2
  0.923315 seconds (799.85 k allocations: 17.608 MB, 0.96% gc time)
  0.922132 seconds (797.96 k allocations: 17.517 MB, 1.08% gc time)