2017-03-16 14 views
2

私はJulia 0.4から0.5まで自分のコードを更新しています。私はいくつかの減速に遭遇しています。 0.5と0.6で、それは周りの0.1376をとりながら、私が遭遇しています何の簡単な例は、(リスト内包付き)0.5と0.6の減速?

x = rand(1:100, (50, 7, 3)) 

function f(a::Int, e::Int, r::Int) 
    x[a-16+1, e-10+1, r] 
end 

y = sum(f(a, e, r) for a in 16:65, e in 10:16, r in 1:3) # in 0.5 and 0.6 
y = sum([f(a, e, r) for a in 16:65, e in 10:16, r in 1:3]) # in 0.4 

0.4の最後の行は、0.0004秒かかります。バージョン0.5と0.6で何が起こっていますか?

+0

リストの理解とジェネレータの表現が遅くなるのではなく、0.5/0.6の減速であることをどのように知っていますか? –

答えて

10

グローバルスコープで非定型のグローバルとタイミングコードを使用しています。 x定数を作成します(または関数の引数として渡す)機能でsum計算を置く:

const x = rand(1:100, (50, 7, 3)) 

function f(a::Int, e::Int, r::Int) 
    x[a-16+1, e-10+1, r] 
end 

g() = sum(f(a, e, r) for a in 16:65, e in 10:16, r in 1:3) # in 0.5 and 0.6 
h() = sum([f(a, e, r) for a in 16:65, e in 10:16, r in 1:3]) # in 0.4 

私はあなたの元のコードを実行したときに報告したように、私はほぼ正確に同じタイミングを参照してください。私が書いたように、コード付き:

0.6.0-pre.alpha.117:

julia> g(); @time g() # Call g() before timing it to compile it 
    0.000020 seconds (9 allocations: 416 bytes) 
53033 

julia> h(); @time h() 
    0.000026 seconds (6 allocations: 8.547 KiB) 
53033 

0.4.7:

julia> h(); @time h() 
    0.000020 seconds (6 allocations: 8.453 KB) 
50658 

それはとても速く、今することができますもはや正確ません1回の実行でベンチマークします。

はい、0.5と0.6は元のケースでは遅くなりました。これは、理解/ジェネレーター用の特別な関数オブジェクトを作成し、コンパイルするためです。したがって、これらの文を最上位レベルで実行すると、毎回編集コストを支払う(そして測定する)ことになります。あなたがそれを関数に入れると、Juliaはそれを一度コンパイルすることができ、その後のすべての呼び出しは非常に高速です。パフォーマンスを最適化することに興味がある場合は、performance tipsをすべて読むことを強くお勧めします。グローバルを避けることは、最初のセクションです。

+0

'const x = rand(1:100、(50,7,3,50,7,3))'でスケールアップして、あなたのような関数でその合計を囲んでいるとします。 0.5と0.6の性能は0.4の性能よりも大幅に遅れています。しかし、明示的なループで合計するとパフォーマンスが向上することに気付きました...私のプロジェクトをループに変更するのは面倒です。 – amrods

+0

あなたはどのバージョンを使用していますか? 0.6.0で固定され、0.5.1でほとんど固定された0.5.0の6次元配列の回帰がありました。 –

+0

正確には、0.5.1と0.6-pre-alpha(昨夜のビルド)です。私はちょうど0.6のリリースを待つべきですか? – amrods