LoginSignup
0
0

More than 3 years have passed since last update.

julia1.2 mapよりforが高速な件 は間違っていた

Last updated at Posted at 2019-11-21

実行環境 julia1.2/MacOS

forとmapの性能差について、聞いてはいたが、どっちが速いのか忘れたので確認してみた。

最初、「mapよりforが高速な件」として書いたのだけれど、その後、間違っていることがわかったので、

以下、間違った記事も残し、最後にやりなおしたコードを含めた。

まず
```julia
xm=collect(1:1000000)
ym=collect(1:1000000)

@show :map
GC.gc()
@time map((x,y)->[x,y],xm,ym)

@show :for
xym=[]
GC.gc()
@time for i in 1:length(xm) ; append!(xym,[xm[i],ym[i]]) end


追記
juliaでは、map((x,y)->[x,y],xs,ys)とするとxsとysの対応する要素のリストが作られる。
forでこれをやろうと思っても、Juliaでは簡単に書けない。つまり、疑似コードで書くと
for x in xs as y in xs ... end
みたいには書けない。
そこで、index ixを1からlength(xs)まで走らせて対応する[xs[ix],ys[ix]]を作ることになり
これだとなんとなく遅くなるのではと思い、上記のテストをしてみたという話。

さらに

'''julia
function elemf(x)
  length(x)
end

function loopm(ls::Array)
  map((x)->elemf(x), ls)
end

function loopf(ls::Array)
  a = []
  for x in ls
    push!(a, elemf(x))
  end
  a
end

ddk=map((x)->[x], collect(1:1000))
@show :size1000
GC.gc()
@show :loopm; @time loopm(ddk)
@show :loopf; @time loopf(ddk)

ddm=map((x)->[x], collect(1:1000000))
@show :size1000000
GC.gc()
@show :loopm; @time loopm(ddm)
@show :loopf; @time loopf(ddm)

ddm=map((x)->[x], collect(1:10000000))
@show :size10000000
GC.gc()
@show :loopm; @time loopm(ddm)
@show :loopf; @time loopf(ddm)

ループの中で重い処理をすれば、mapとforの違いは無視できるのかと思い、
こういうことをしてみた。

:size1000 = :size1000
:loopm = :loopm
  0.025073 seconds (83.41 k allocations: 4.265 MiB)
:loopf = :loopf
  0.014806 seconds (8.37 k allocations: 405.388 KiB)
:size1000000 = :size1000000
:loopm = :loopm
  0.007201 seconds (7 allocations: 7.630 MiB)
:loopf = :loopf
  0.021993 seconds (24 allocations: 9.001 MiB)
:size10000000 = :size10000000
:loopm = :loopm
  0.086593 seconds (7 allocations: 76.294 MiB)
:loopf = :loopf
  0.260839 seconds (28 allocations: 129.001 MiB)

となった。
mapのほうはサイズがかわっても処理時間はあまりかわらない。
mapのほうが高速ということか。

先の例でも1000個を1000000個にしたらmapのほうが速かった。

xm=collect(1:1000000)
ym=collect(1:1000000)

@show :map
GC.gc()
@time map((x,y)->[x,y],xm,ym)


@show :for
xym=[]
GC.gc()
@time for i in 1:length(xm) ; append!(xym,[xm[i],ym[i]]) end

を実行した結果は以下のとおり。

:map = :map
  0.273464 seconds (1.07 M allocations: 102.574 MiB, 61.44% gc time)
:for = :for
  0.530627 seconds (8.00 M allocations: 230.577 MiB, 41.02% gc time)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0