首先,让我们创建一个你所说的文件以提供可重复性:
open("myFile.txt", "w") do io
foreach(i -> println(io, join(i+1:i+644, '|')), 1:153895)
end
现在我正在Julia 1.4.2和CSV.jl 0.7.1中读取此文件。
单线程:
julia> @time CSV.File("myFile.txt", delim='|', header=false);
4.747160 seconds (1.55 M allocations: 1.281 GiB, 4.29% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
2.780213 seconds (13.72 k allocations: 1.206 GiB, 5.80% gc time)
并使用例如4个线程:
julia> @time CSV.File("myFile.txt", delim='|', header=false);
4.546945 seconds (6.02 M allocations: 1.499 GiB, 5.05% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
0.812742 seconds (47.28 k allocations: 1.208 GiB)
在 R 中,它是这样的:
> system.time(myData<-read.delim("myFile.txt",sep="|",header=F,
+ stringsAsFactors=F,na.strings=""))
user system elapsed
28.615 0.436 29.048
在Python(Pandas)中,它是这样的:
>>> import pandas as pd
>>> import time
>>> start=time.time()
>>> myData=pd.read_csv("myFile.txt",sep="|",header=None,low_memory=False)
>>> print(time.time()-start)
25.95710587501526
现在,如果我们从R中测试fread
(非常快速的函数),我们得到:
> system.time(fread("myFile.txt", sep="|", header=F,
stringsAsFactors=F, na.strings="", nThread=1))
user system elapsed
1.043 0.036 1.082
> system.time(fread("myFile.txt", sep="|", header=F,
stringsAsFactors=F, na.strings="", nThread=4))
user system elapsed
1.361 0.028 0.416
因此,在这种情况下,总结如下:
- 尽管在Julia中编译
CSV.File
的成本很高,但是当您第一次运行它时,它比基本的R或Python快得多。
- 它的速度与R中的
fread
相当(在这种情况下稍微慢一些,但其他的基准测试 (在这里)也显示了它更快的情况)。
编辑:根据要求,我添加了一个小文件的基准测试:10列,100,000行的Julia和Pandas。
数据准备步骤:
open("myFile.txt", "w") do io
foreach(i -> println(io, join(i+1:i+10, '|')), 1:100_000)
end
CSV.jl,单线程:
julia> @time CSV.File("myFile.txt", delim='|', header=false);
1.898649 seconds (1.54 M allocations: 93.848 MiB, 1.48% gc time)
julia> @time CSV.File("myFile.txt", delim='|', header=false);
0.029965 seconds (248 allocations: 17.037 MiB)
Pandas:
>>> import pandas as pd
>>> import time
>>> start=time.time()
>>> myData=pd.read_csv("myFile.txt",sep="|",header=None,low_memory=False)
>>> print(time.time()-start)
0.07587623596191406
结论:
- 编译成本是一次性的成本,必须付出并且它是恒定的(粗略地说,它不取决于要读取的文件有多大)
- 对于小文件,如果我们排除编译成本,CSV.jl比Pandas更快
现在,如果您想避免在每个新的Julia会话中支付编译成本,可以使用https://github.com/JuliaLang/PackageCompiler.jl。
根据我的经验,如果您正在进行数据科学工作,例如读入数千个CSV文件,我不介意等待2秒钟进行编译,以后可以节省几个小时。编写读取文件的代码花费的时间超过了2秒钟。
当然 - 如果您编写一个仅执行少量工作并在完成后终止的脚本,则编译时间实际上将是计算成本的主要部分。在这种情况下,我使用PackageCompiler.jl策略。
fread
读取文件。当读取数据时,在第12141行的字段412上,出现了错误Expected sep ('|') but '"' ends field 412 on line 12141 when reading data: ...
。字段412中有一个包含两个"
的字符串,导致fread
出现问题。此外,以它的速度读取到第12141行,总时间理论上只需要36.1秒,因此可能比read.delim
有显著的改进。 - uday