user3756502 user3756502 - 10 months ago 53
Linux Question

Ruby sysread IO much too slow

I have a command like this:


is a string that receives the input.)

But if it reads more than 100 characters it takes more than 0.1 seconds.

I tried it with alternatives such as
and nonblocking reading and
, but I didn't find a faster alternative so far.

Do you know any faster possibility to simply read this sh***?

Many thanks!


is bigger than 0.1
if input.length > 100

I read mouse movements from terminal within X-Window.

Does sysread wait for more input than available before it finishes execution?

Answer Source

There is probably something odd in your benchmarking setup. What comes to mind first is that your sender might not write fast enough.

The following benchmark (using benchmark-ips) resulted in approximately one read every 1.3 micro-seconds on my 4-years-old Macbook on Ruby 2.2.5.

This benchmark contains additional code to verify that we are reading exactly 1000-character strings. This makes the benchmark almost 50% slower, but still much faster than you claim.

require 'benchmark/ips'

sysread_1k_strings = 0
read_1k_strings = 0

Benchmark.ips do |x|
  input = ''

  x.warmup = 0'sysread') {
    STDIN.sysread(1000, input)
    sysread_1k_strings += 1 if input.length == 1000
  }'read') {, input)
    read_1k_strings += 1 if input.length == 1000


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"

When reading from /dev/zero this resulted in the following benchmark result:

$ 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