module SimpleCov
  module RawCoverage
  module_function

    # Merges multiple Coverage.result hashes
    def merge_results(*results)
      results.reduce({}) do |result, merged|
        merge_resultsets(result, merged)
      end
    end

    # Merges two Coverage.result hashes
    def merge_resultsets(result1, result2)
      (result1.keys | result2.keys).each_with_object({}) do |filename, merged|
        file1 = result1[filename]
        file2 = result2[filename]
        merged[filename] = merge_file_coverage(file1, file2)
      end
    end

    def merge_file_coverage(file1, file2)
      return (file1 || file2).dup unless file1 && file2

      file1.zip(file2).map do |count1, count2|
        merge_line_coverage(count1, count2)
      end
    end

    def merge_line_coverage(count1, count2)
      sum = count1.to_i + count2.to_i
      if sum.zero? && (count1.nil? || count2.nil?)
        nil
      else
        sum
      end
    end
  end
end

module SimpleCov
  module RawCoverage
  module_function

    # Merges multiple Coverage.result hashes
    def merge_results(*results)
      results.reduce({}) do |result, merged|
        merge_resultsets(result, merged)
      end
    end

    # Merges two Coverage.result hashes
    def merge_resultsets(result1, result2)
      (result1.keys | result2.keys).each_with_object({}) do |filename, merged|
        file1 = result1[filename]
        file2 = result2[filename]
        merged[filename] = merge_file_coverage(file1, file2)
      end
    end

    def merge_file_coverage(file1, file2)
      return (file1 || file2).dup unless file1 && file2

      file1.map.with_index do |count1, index|
        count2 = file2[index]
        merge_line_coverage(count1, count2)
      end
    end

    def merge_line_coverage(count1, count2)
      sum = count1.to_i + count2.to_i
      if sum.zero? && (count1.nil? || count2.nil?)
        nil
      else
        sum
      end
    end
  end
end

Use map.with_index instead of zip for performance
Use map.with_index instead of zip for performance

  $ cat bench.rb
  require "benchmark/ips"

  a = Array.new(100) { 1 }.freeze
  b = Array.new(100) { 2 }.freeze

  Benchmark.ips do |x|
    x.report('lazy.zip.map.to_a') { a.lazy.zip(b).map {|l,r| l + r }.to_a }
    x.report('zip.map') { a.zip(b).map {|l,r| l + r } }
    x.report('map.with_index') { a.map.with_index {|i,index| i + b[index] } }
    x.report('each_with_index') do |times|
      new_array = []
      i = 0
      while i < times
        a.each_with_index {|i,index| new_array << i + b[index] }
        i = i + 1
      end
    end
    x.compare!
  end
  $ ruby bench.rb
  Warming up --------------------------------------
     lazy.zip.map.to_a     1.450k i/100ms
               zip.map     7.869k i/100ms
        map.with_index    10.748k i/100ms
       each_with_index     9.976k i/100ms
  Calculating -------------------------------------
     lazy.zip.map.to_a     13.688k (±14.1%) i/s -     68.150k in   5.097768s
               zip.map     79.369k (± 8.6%) i/s -    393.450k in   5.005312s
        map.with_index    110.505k (± 4.0%) i/s -    558.896k in   5.067126s
       each_with_index    114.300k (± 4.2%) i/s -    578.608k in   5.071720s

  Comparison:
       each_with_index:   114300.5 i/s
        map.with_index:   110505.2 i/s - same-ish: difference falls within error
               zip.map:    79368.7 i/s - 1.44x  slower
     lazy.zip.map.to_a:    13688.2 i/s - 8.35x  slower
