我正在处理大量数据文件(每个数百万行).
在开始处理之前,我想得到文件中行数的计数,然后我可以指出处理的距离.
由于文件的大小,将整个文件读入内存是不切实际的,只计算有多少行.有没有人对如何做到这一点有一个很好的建议?
gle*_*man 74
一次读取一行文件:
count = File.foreach(filename).inject(0) {|c, line| c+1}
Run Code Online (Sandbox Code Playgroud)
或Perl-ish
File.foreach(filename) {}
count = $.
Run Code Online (Sandbox Code Playgroud)
要么
count = 0
File.open(filename) {|f| count = f.read.count("\n")}
Run Code Online (Sandbox Code Playgroud)
会慢一些
count = %x{wc -l #{filename}}.split.first.to_i
Run Code Online (Sandbox Code Playgroud)
DJ.*_*DJ. 67
如果你在Unix环境中,你可以放手去做wc -l.
它不会将整个文件加载到内存中; 因为它针对流文件和计数字/行进行了优化,所以性能足够好,而不是自己在Ruby中流式传输文件.
SSCCE:
filename = 'a_file/somewhere.txt'
line_count = `wc -l "#{filename}"`.strip.split(' ')[0].to_i
p line_count
Run Code Online (Sandbox Code Playgroud)
或者,如果您想要在命令行上传递的文件集合:
wc_output = `wc -l "#{ARGV.join('" "')}"`
line_count = wc_output.match(/^ *([0-9]+) +total$/).captures[0].to_i
p line_count
Run Code Online (Sandbox Code Playgroud)
cle*_*tus 15
无论你使用什么语言都没关系,如果行长度可变,你将不得不阅读整个文件.那是因为新行可能在任何地方,如果没有读取文件就没有办法知道(假设它没有被缓存,一般来说它不是).
如果要指示进度,则有两个实际选项.您可以根据假定的行长度推断进度:
assumed lines in file = size of file / assumed line size
progress = lines processed / assumed lines in file * 100%
Run Code Online (Sandbox Code Playgroud)
因为你知道文件的大小.或者,您可以测量进度:
progress = bytes processed / size of file * 100%
Run Code Online (Sandbox Code Playgroud)
这应该足够了.
JBo*_*Boy 11
使用红宝石:
file=File.open("path-to-file","r")
file.readlines.size
Run Code Online (Sandbox Code Playgroud)
比325.477行文件上的wc -l快39毫秒
Exs*_*emt 10
已发布解决方案的摘要
require 'benchmark'
require 'csv'
filename = "name.csv"
Benchmark.bm do |x|
x.report { `wc -l < #{filename}`.to_i }
x.report { File.open(filename).inject(0) { |c, line| c + 1 } }
x.report { File.foreach(filename).inject(0) {|c, line| c+1} }
x.report { File.read(filename).scan(/\n/).count }
x.report { CSV.open(filename, "r").readlines.count }
end
Run Code Online (Sandbox Code Playgroud)
文件807802行:
user system total real
0.000000 0.000000 0.010000 ( 0.030606)
0.370000 0.050000 0.420000 ( 0.412472)
0.360000 0.010000 0.370000 ( 0.374642)
0.290000 0.020000 0.310000 ( 0.315488)
3.190000 0.060000 3.250000 ( 3.245171)
Run Code Online (Sandbox Code Playgroud)
免责声明:使用已经存在的基准测试count而不是lengthor size(在 ruby 中这是出了名的慢)。恕我直言,阅读起来很乏味。因此有了这个新答案。
require "benchmark"\nrequire "benchmark/ips"\nrequire "csv"\n\nfilename = ENV.fetch("FILENAME")\n\nBenchmark.ips do |x|\n x.report("wc") { `wc -l #{filename}`.to_i }\n x.report("open") { File.open(filename).inject(0, :next) }\n x.report("foreach") { File.foreach(filename).inject(0, :next) }\n x.report("foreach $.") { File.foreach(filename) {}; $. }\n x.report("read.scan.length") { File.read(filename).scan(/\\n/).length }\n x.report("CSV.open.readlines") { CSV.open(filename, "r").readlines.length }\n x.report("IO.readlines.length") { IO.readlines(filename).length }\n\n x.compare!\nend\nRun Code Online (Sandbox Code Playgroud)\n在配备 2.3 GHz Intel Core i5 处理器的 MacBook Pro (2017) 上:
\nWarming up --------------------------------------\n wc 8.000 i/100ms\n open 2.000 i/100ms\n foreach 2.000 i/100ms\n foreach $. 2.000 i/100ms\n read.scan.length 2.000 i/100ms\n CSV.open.readlines 1.000 i/100ms\n IO.readlines.length 2.000 i/100ms\nCalculating -------------------------------------\n wc 115.014 (\xc2\xb121.7%) i/s - 552.000 in 5.020531s\n open 22.450 (\xc2\xb126.7%) i/s - 104.000 in 5.049692s\n foreach 32.669 (\xc2\xb127.5%) i/s - 150.000 in 5.046793s\n foreach $. 25.244 (\xc2\xb131.7%) i/s - 112.000 in 5.020499s\n read.scan.length 44.102 (\xc2\xb131.7%) i/s - 190.000 in 5.033218s\n CSV.open.readlines 2.395 (\xc2\xb141.8%) i/s - 12.000 in 5.262561s\n IO.readlines.length 36.567 (\xc2\xb127.3%) i/s - 162.000 in 5.089395s\n\nComparison:\n wc: 115.0 i/s\n read.scan.length: 44.1 i/s - 2.61x slower\n IO.readlines.length: 36.6 i/s - 3.15x slower\n foreach: 32.7 i/s - 3.52x slower\n foreach $.: 25.2 i/s - 4.56x slower\n open: 22.4 i/s - 5.12x slower\n CSV.open.readlines: 2.4 i/s - 48.02x slower\nRun Code Online (Sandbox Code Playgroud)\n这是由包含 75 516 行和 3 532 510 个字符(每行约 47 个字符)的文件创建的。您应该使用自己的文件/尺寸和计算机尝试此操作以获得精确的结果。
\n| 归档时间: |
|
| 查看次数: |
43221 次 |
| 最近记录: |