Julia 将文本文件存储为二进制文件以加快读/写速度

Julia 将文本文件存储为二进制文件以加快读/写速度,julia,binaryfiles,Julia,Binaryfiles,我有一大组需要处理的文本文件。由于pmap(),现在的性能非常好,但我正在寻找额外的加速。当前的瓶颈是将字符串解析为浮点数 我曾想过加载我的数据(管道分隔的文本文件)并将其写入二进制格式。据我所见,Julia应该能够以这种方式更快地加载我的数据。问题是,在将二进制数据写入Julia后,如何正确地将其加载回Julia中,我遇到了一些问题 下面是一些用于加载、解析和写入二进制文件的示例代码: input_file = "/cool/input/file.dat" ## -- pipe delim

我有一大组需要处理的文本文件。由于
pmap()
,现在的性能非常好,但我正在寻找额外的加速。当前的瓶颈是将字符串解析为浮点数

我曾想过加载我的数据(管道分隔的文本文件)并将其写入二进制格式。据我所见,Julia应该能够以这种方式更快地加载我的数据。问题是,在将二进制数据写入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
问题是,当我将上述文件加载到Julia中时,我不知道这些值是什么:

read(output_file)
n-element Array{UInt8,1}:
 0x00
 0x00
 0x00
 0x00
 0x00
 0x80
 0x16

如何在Julia代码中使用这些二进制值作为浮点数?更一般地说,如果我想提高性能,用这种方式将文本文件数据转换成二进制文件有意义吗

我不知道实际的加速速度有多快,但我在存储大量非结构化变量集合时使用了一些东西(与存储在关系数据库/.json文件中的东西相反)

您需要使用
重新解释
函数:

帮助?>重新解释
搜索:重新解释
重新解释(类型,A)
更改内存块的类型解释。例如
重新解释(Float32,UInt32(7))解释对应的4个字节
将UInt32(7)作为浮点数32。对于数组,这将使用
与给定数组相同的二进制数据,但具有指定的元素
类型。

用于写入数字数据的函数:

julia>函数写入数据{T data=rand(10)
10元素数组{Float64,1}:
0.986948
0.616107
0.504965
0.673264
0.0358904
0.1795
0.399481
0.233351
0.320968
0.16746
函数,用于读取二进制数据并将其重新解释为数字数据类型:

julia>函数读取数据{T读取数据(“foo.bin”,Float64)
10元素数组{Float64,1}:
0.986948
0.616107
0.504965
0.673264
0.0358904
0.1795
0.399481
0.233351
0.320968
0.16746
重新解释为
Float32
,自然会产生两倍的数据:

julia>读取数据(“foo.bin”,Float32)
20元素数组{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.915F-25
1.54246

用于从julia会话的工作区“保存”数据的官方解决方案/格式是

可以将其视为matlab中的
.mat
文件,或者python中的
搁置

或者,您可以使用
serialize
命令将数据直接序列化到文件中(不过,请阅读JLD页面中的注意事项)

如果您需要在问题中描述的这种特定的“自制”序列化方法来处理特定的项目,那么很好。但除此之外,听起来您一般都希望高效地存储和访问序列化数据,所以请改用JLD

例如:

### in file "floats.dat"
1.0|2.0|3.0|4.0|5.0|6.0|7.0|8.0|9.0|10.0

只是要确保这不是一个场景:您需要这种特定格式是有非常具体的原因,还是您只是想找到一种有效的方法将预处理的数据保存/加载到磁盘以供以后处理?只是想找到一种更有效的方法来保存/加载数据。我将查看JLD.jl。谢谢,这很有用。这里有一个跟进。是吗可以用二进制写/读二维数组,或者数据只能存储为向量吗?@JeremyMcNees你总是可以重塑生成的向量,但我真的认为这是IMO的方法,即使用JLD;保存(“mat.JLD”,“mat”,rand(2,2));加载(“mat.JLD”)[“mat”]将保存并加载
rand(2,2)
matrix使用HDF5。谢谢。这可能是我正在尝试的一种更好的方法。我将查看此软件包。
# Using .jld files
julia> using JLD
julia> S = split( chomp( readstring("floats.dat")), '|');
julia> Floats = [parse(Float64, x) for x in S];
julia> save("myFloats.jld","Floats",Floats)
julia> load("myFloats.jld")
Dict{String,Any} with 1 entry:
  "Floats" => [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0]
# Using serialize / deserialize
julia> S = split( chomp( readstring("floats.dat")), '|');
julia> Floats = [parse(Float64, x) for x in S];
julia> f = open("out.dat", "w"); serialize(f, Floats); close(f);
julia> f = open("out.dat", "r"); show(deserialize(f))
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0]