Array でしていた計算を、JuliaDB の table ですると早くなる例その2

Array でしていた計算を、JuliaDB の table ですると早くなる例その2です。

ユークリッド距離の2乗の距離行列を求めてみましょう。データの例は、かって知りたる iris です。

iris を読み込んで、Array と table (正確には、IndexedTables.NextTable) に変換します。

using RDatasets, DataFrames, JuliaDB

iris = dataset("datasets", "iris")

A = Array(iris[:,1:4])

table_iris = table(iris[:,1:4])

table への変換は、Array からの変換は結構、面倒で、DataFrame を1回通す方が楽です。ただし、この場合、DataFrames と JuliaDB が一緒に動くので、後から立ち上げた方の stack, aggregate、 groupby などが使えなくなることがあります。

では、おたがいの距離行列の計算式を関数化します。

# JuliaDB

  function tb_dist(indexed_table::IndexedTables.NextTable)
    dist_mat = [sum((rows(indexed_table)[i] .- rows(indexed_table)[1]).^2) for i in 1:length(indexed_table)]
    for j in 2:length(indexed_table)
      dist_mat = hcat(
        dist_mat,
        [sum((rows(indexed_table)[i] .- rows(indexed_table)[j]).^2) for i in 1:length(indexed_table)]
      )
    end
    return dist_mat
  end


#Array

  function Array_dist(A::Array)
      dist_mat = [ sum((A[i,:] .- A[1,:]).^2) for i in 1:size(A)[1]]
    for j in 2:size(A)[1]
      dist_mat = hcat(
          dist_mat,
          [ sum((A[i,:] .- A[j,:]).^2) for i in 1:size(A)[1]]
        )
    end
    return dist_mat
  end

再帰的に書いているので、読み難いかもしれませんが、形は一緒です。

では、お楽しみの時間測定です。

  julia> for i in 1:5; @time tb_dist(tb_iris); end
  0.024816 seconds (181.48 k allocations: 18.685 MiB)
  0.042909 seconds (181.48 k allocations: 18.685 MiB, 43.25% gc time)
  0.051451 seconds (181.48 k allocations: 18.685 MiB, 23.65% gc time)
  0.038076 seconds (181.48 k allocations: 18.685 MiB, 25.34% gc time)
  0.035940 seconds (181.48 k allocations: 18.685 MiB, 24.48% gc time)
  julia> for i in 1:5; @time Array_dist(A); end
  0.284643 seconds (784.48 k allocations: 46.666 MiB, 7.35% gc time)
  0.291637 seconds (784.48 k allocations: 46.666 MiB, 6.07% gc time)
  0.293948 seconds (784.48 k allocations: 46.666 MiB, 5.17% gc time)
  0.293481 seconds (784.48 k allocations: 46.666 MiB, 7.67% gc time)
  0.289398 seconds (784.48 k allocations: 46.666 MiB, 8.02% gc time)

DataFrame と同じような使い方をしているだけです。しかし、1桁、JuliaDB の方が早いです。 やはり、JuliaDB って、すごい気がします。使えるなら使う方が良いみたいです。

B! LINE