将文本文件存储为二进制文件以便更快地读/写

Jer*_*ees 4 binaryfiles julia

我有一大堆需要处理的文本文件.现在表现非常好,多亏了pmap(),但我正在寻找额外的加速.当前的瓶颈是将字符串解析为浮点数.

我想到了加载我的数据(管道分隔的文本文件)并将它们写成二进制格式.从我所看到的,Julia应该能够以这种方式更快地加载我的数据.问题是我在将二进制数据写成二进制文件后将其加载回Julia的正确方法遇到了一些麻烦.

这是我用于加载,解析和写入二进制文件的一些示例代码:

input_file = "/cool/input/file.dat"   ## -- pipe delimited text file of Floats
output_file = "/cool/input/data_binary" 

open(input_file, "r") do in_file
    open(output_file, "w") do out_file
        for line in eachline(in_file)
            split_line = split(line, '|')
            out_float = parse(Float64, split_line[4])
            write(out_file, out_float)
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

问题是,当我将上述文件加载到Julia时,我不知道值是什么:

read(output_file)
n-element Array{UInt8,1}:
 0x00
 0x00
 0x00
 0x00
 0x00
 0x80
 0x16
Run Code Online (Sandbox Code Playgroud)

如何在Julia代码中将这些二进制值用作浮点数?更一般地说,如果我正在寻找性能提升,以这种方式将我的文本文件数据转换为二进制文件是否有意义?

Sal*_*apa 6

你需要使用这个reinterpret功能:

help?> reinterpret
search: reinterpret

  reinterpret(type, A)

  Change the type-interpretation of a block of memory. For example,
  reinterpret(Float32, UInt32(7)) interprets the 4 bytes corresponding
  to UInt32(7) as a Float32. For arrays, this constructs an array with 
  the same binary data as the given array, but with the specified element
  type.
Run Code Online (Sandbox Code Playgroud)

写入数字数据的功能:

julia> function write_data{T<:Number}(file_name::String, data::AbstractArray{T})
           open(file_name, "w") do f_out
               for i in data
                   write(f_out, i)
               end
           end
       end
write_data (generic function with 1 method)
Run Code Online (Sandbox Code Playgroud)

随机数据:

julia> data = rand(10)
10-element Array{Float64,1}:
 0.986948
 0.616107
 0.504965
 0.673264
 0.0358904
 0.1795
 0.399481
 0.233351
 0.320968
 0.16746
Run Code Online (Sandbox Code Playgroud)

读取二进制数据并将其重新解释为数字数据类型的函数:

julia> function read_data{T<:Number}(file_name::String, dtype::Type{T})
           open(file_name, "r") do f_in
               reinterpret(dtype, read(f_in))
           end
       end
read_data (generic function with 1 method)
Run Code Online (Sandbox Code Playgroud)

将样本数据读取为Float64s会生成我们编写的相同数组:

julia> read_data("foo.bin", Float64)
10-element Array{Float64,1}:
 0.986948
 0.616107
 0.504965
 0.673264
 0.0358904
 0.1795
 0.399481
 0.233351
 0.320968
 0.16746
Run Code Online (Sandbox Code Playgroud)

重新解释为Float32,自然产生两倍的数据:

julia> read_data("foo.bin", Float32)
20-element Array{Float32,1}:
  1.4035f7
  1.87174
 -9.17366f25
  1.77903
 -1.03106f-24
  1.75124
  1.9495f-20
  1.79332
  2.88032f-21
  1.26856
  1.17736f19
  1.5545
 -3.25944f-18
  1.69974
  5.25285f-17
  1.60835
 -3.46489f14
  1.66048
  1.91915f-25
  1.54246
Run Code Online (Sandbox Code Playgroud)