ruby快速阅读标准
什么是从STDIN读取多个1000000个字符(整数)的最快方法,并将其拆分为一个字符整数(不是字符串)的数组?
123456 > [1,2,3,4,5,6]
这应该相当快:
a = [] STDIN.each_char do |c| a << c.to_i end
虽然一些粗略的基准测试显示这个hackish版本相当快:
a = STDIN.bytes.map { |c| c-48 }
我到目前为止找到的最快捷方法如下: –
gets.unpack("c*").map { |c| c-48}
以下是对大多数提供的解决方案进行基准测试的一些结果。 这些测试使用100,000个数字文件运行,但每个测试有10个代表。
用户系统总真实 each_char_full_array:1.780000 0.010000 1.790000(1.788893) each_char_empty_array:1.560000 0.010000 1.570000(1.572162) map_byte:0.760000 0.010000 0.770000(0.773848) gets_scan 2.220000 0.030000 2.250000(2.250076) 解包:0.510000 0.020000 0.530000(0.529376)
以下是生成它们的代码
#!/usr/bin/env ruby require "benchmark" MAX_ITERATIONS = 100000 FILE_NAME = "1_million_digits" def build_test_file File.open(FILE_NAME, "w") do |f| MAX_ITERATIONS.times {|x| f.syswrite rand(10)} end end def each_char_empty_array STDIN.reopen(FILE_NAME) a = [] STDIN.each_char do |c| a << c.to_i end a end def each_char_full_array STDIN.reopen(FILE_NAME) a = Array.new(MAX_ITERATIONS) idx = 0 STDIN.each_char do |c| a[idx] = c.to_i idx += 1 end a end def map_byte() STDIN.reopen(FILE_NAME) a = STDIN.bytes.map { |c| c-48 } a[-1] == -38 && a.pop a end def gets_scan STDIN.reopen(FILE_NAME) gets.scan(/\d/).map(&:to_i) end def unpack STDIN.reopen(FILE_NAME) gets.unpack("c*").map { |c| c-48} end reps = 10 build_test_file Benchmark.bm(10) do |x| x.report("each_char_full_array: ") { reps.times {|y| each_char_full_array}} x.report("each_char_empty_array:") { reps.times {|y| each_char_empty_array}} x.report("map_byte: ") { reps.times {|y| map_byte}} x.report("gets_scan ") { reps.times {|y| gets_scan}} x.report("unpack: ") { reps.times {|y| unpack}} end
scan(/\d/).map(&:to_i)
这会将任何字符串拆分为整数数组,而忽略任何非数字字符。 如果你想从STDIN获取用户输入add gets:
gets.scan(/\d/).map(&:to_i)