Ruby sysread IO太慢了

时间:2016-10-11 18:12:04

标签: ruby linux api io

我有一个这样的命令,其中input是一个接收输入的字符串:

STDIN.sysread(1000,input)

如果超过100个字符,则需要超过0.1秒。

我尝试使用partialread和非阻塞阅读以及read等替代方案,但到目前为止我还没有找到更快的替代方案。

你知道更简单地读这个的可能性吗?

t=Time.now
STDIN.sysread(1000,input)
stdin_time=Time.now-t

stdin_time大于0.1 if input.length > 100

我在X-Window中从终端读取鼠标移动。

sysread在完成执行之前是否等待比可用的更多输入?

即使这样也不起作用:

t=Time.now
Thread.new{
    input=STDIN.sysread(1000)
}.join(0.001)
stdin_time=Time.now-t

stdin_time仍然> 0.01,与以前一样。

移动鼠标时屏幕上可以看到0.01秒。它不仅是理论上的数字问题,而且是可见的。问题肯定存在。

1 个答案:

答案 0 :(得分:1)

您的基准测试设置可能有些奇怪。首先想到的是你的发件人写得不够快。

以下基准测试(使用benchmark-ips)导致我在Ruby 2.2.5上使用4年历史的Macbook上每1.3微秒大约读取一次。

此基准测试包含额外的代码,用于验证我们是否正在读取1000个字符的字符串。这使得基准测试速度降低了近50%,但仍然比你声称的更快

require 'benchmark/ips'

sysread_1k_strings = 0
read_1k_strings = 0

Benchmark.ips do |x|
  input = ''

  x.warmup = 0

  x.report('sysread') {
    STDIN.sysread(1000, input)
    sysread_1k_strings += 1 if input.length == 1000
  }

  x.report('read') {
    STDIN.read(1000, input)
    read_1k_strings += 1 if input.length == 1000
  }

end

puts "Comparison --------------------------------------"
puts "sysread".rjust(20) + "#{sysread_1k_strings.to_s.rjust(11)} 1000 byte strings read"
puts "read".rjust(20) + "#{read_1k_strings.to_s.rjust(11)} 1000 byte strings read"

/dev/zero阅读时,会产生以下基准测试结果:

$ ruby benchmark.rb < /dev/zero
Warming up --------------------------------------
             sysread     1.000  i/100ms
                read     1.000  i/100ms
Calculating -------------------------------------
             sysread    210.517k (±13.5%) i/s -    915.780k in   4.529414s
                read    475.210k (±10.4%) i/s -      1.956M in   4.209967s
Comparison --------------------------------------
             sysread     915780 1000 byte strings read
                read    1955737 1000 byte strings read