The Computer Language
Benchmarks Game

reverse-complement Ruby program

source code

# The Computer Language Benchmarks Game
# http://benchmarksgame.alioth.debian.org
#
# Contributed by Aaron Tavistock

def process_segment(segment)
  (header, *body, tail) = segment.split("\n")

  # This is an ugly way to handle the first row, but returning nil causes the fork to implode
  return '' if !tail
  body << tail if tail != '>'

  sequence = body.join
  sequence.reverse!
  sequence.tr!(
    'wsatugcyrkmbdhvnATUGCYRKMBDHVN',
    'WSTAACGRYMKVHDBNTAACGRYMKVHDBN'
  )

  results = [">#{header}"]

  idx = 0
  length = sequence.length
  while idx < length
    results << sequence[idx,60]
    idx += 60
  end

  results.join("\n")
end

def forking_worker(segment)
  reader, writer = IO.pipe

  pid = Process.fork do
    begin
      reader.close
      results = process_segment(segment)
      Marshal.dump(results, writer) if results
    ensure
      writer.close
    end
  end

  writer.close
  begin
    results = Marshal.load(reader)
  ensure
    reader.close
  end
  Process.waitpid(pid)

  results
end

threads = []
$stdin.each_line('>') do |segment|
  threads << Thread.new do
    if RUBY_PLATFORM == 'java'
      Thread.current[:output] = process_segment(segment)
    else
      Thread.current[:output] = forking_worker(segment)
    end
  end
end
threads.each(&:join)
threads.each do |thread|
  if !thread[:output].empty?  # Artifact of non-empty results from forking worker
    puts thread[:output]
  end
end
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]


Mon, 26 Mar 2018 23:10:55 GMT

COMMAND LINE:
/opt/src/ruby-2.5.0/bin/ruby -W0 revcomp.yarv 0 < revcomp-input100000000.txt

PROGRAM FAILED 


PROGRAM OUTPUT:

revcomp.yarv:35:in `fork': failed to allocate memory (NoMemoryError)
#<Thread:0x0000556b721dffa0@revcomp.yarv:58 run> terminated with exception (report_on_exception is true):
revcomp.yarv:47:in `load': end of file reached (EOFError)
	from revcomp.yarv:47:in `forking_worker'
	from revcomp.yarv:62:in `block (2 levels) in <main>'
revcomp.yarv:47:in `load': end of file reached (EOFError)
	from revcomp.yarv:47:in `forking_worker'
	from revcomp.yarv:62:in `block (2 levels) in <main>'