LoginSignup
15
11

More than 3 years have passed since last update.

Julia でデータを読み書きする

Last updated at Posted at 2018-06-26

動機

シミュレーション結果をアニメーション化するとき、結果をバッファしておかないと、

  • もしアニメーション化でコケてしまったら、完全にデータが失われてしまう
  • アニメーション化の前処理を変更する場合でも、改めてシミュレーションしなければいけない

そこで、(主にシーケンシャルな)データの読み書き例をまとめておきたい。

Julia でデータのセーブとロード

julia> versioninfo()

Julia Version 0.6.3
Commit d55cadc350 (2018-05-28 20:20 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, sandybridge)

バイナリ

Write

@time open("test.dat", "w") do file
    for i in 1:150
        write(file, rand(Float64, 360, 640))
    end
end

1.574172 seconds (2.08 k allocations: 263.777 MiB)

Read

@time open("test.dat", "r") do file
    while !eof(file)
        read(file, Float64, 360, 640)
    end
end

0.801313 seconds (1.45 k allocations: 263.747 MiB)

Read using Memory-mapped I/O

Mmap.mmap は、メモリマッピングを利用して、ファイルにリンクした値をもつ配列を作成する
https://docs.julialang.org/en/stable/stdlib/io-network/#Memory-mapped-I/O-1

@time open("test.dat", "r") do file
    A = Mmap.mmap(file, Array{Float64, 3}, (360, 640, 150))

    for i in 1:150
        A[:, :, i]
    end
end

0.916359 seconds (2.51 k allocations: 263.789 MiB)

逆順にアクセスしても、特に遅くはならなかった。

HDF5 (JLD2)

説明

HDF5 (Hierarchical Data Format)

汎用(特に科学技術計算向き?)の階層化されたファイルフォーマット。
HDF5.jl は外部の HDF5 ライブラリを参照する。

HDF5フォーマットに関するメモ書き

JLD (Julia Data format)

HDF5 の「方言」。
JLD.jl は HDF5.jl を参照する。

JLD2

JLD2 は HDF5 のサブセットで構成されるフォーマット。
JLD との前方・後方互換性は意図されていない。
JLD2.jl は HDF5 ライブラリに依存しない。
JLD.jl と比べて速い(と書いてある)。

Write

  • 辞書型(キーと値のセット)のようにアクセスする
  • 連番文字列でキーを生成した
using JLD2

@time jldopen("test.jld2", "w") do file
    JLD2.Group(file, "data1")

    for i in 1:150
        file["data1"][@sprintf("%08d", i)] = rand(Float64, 360, 640)
    end
end

1.675943 seconds (10.96 k allocations: 264.259 MiB)

Read

@time jldopen("test.jld2", "r") do file
    @assert issorted(keys(file["data1"]))

    for i in keys(file["data1"])
        file["data1"][i]
    end
end

0.810206 seconds (4.60 k allocations: 263.883 MiB)

Read/Write ともに、速度はバイナリとあまり変わらない。

複合体の読み書き例

2020/8/9 追記

struct Hoge{T1,T2}
    a::T1
    b::T2
end

x = Hoge(3.5, true)
write("hoge.bin", Ref(x))

y = Ref{typeof(x)}()
open("hoge.bin") do f
    unsafe_read(f, y, sizeof(y))
end

y[] # Hoge{Float64,Bool}(3.5, true)
15
11
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
15
11