Array Merge (Union)

前端 未结 4 1316
没有蜡笔的小新
没有蜡笔的小新 2020-12-13 18:24

I have two array I need to merge, and using the Union (|) operator is PAINFULLY slow.. are there any other ways to accomplish an array merge?

Also, the arrays are fi

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-13 19:03

    Here's a script which benchmarks two merge techniques: using the pipe operator (a1 | a2), and using concatenate-and-uniq ((a1 + a2).uniq). Two additional benchmarks give the time of concatenate and uniq individually.

    require 'benchmark'
    
    a1 = []; a2 = []
    [a1, a2].each do |a|
      1000000.times { a << rand(999999) }
    end
    
    puts "Merge with pipe:"
    puts Benchmark.measure { a1 | a2 }
    
    puts "Merge with concat and uniq:"
    puts Benchmark.measure { (a1 + a2).uniq }
    
    puts "Concat only:"
    puts Benchmark.measure { a1 + a2 }
    
    puts "Uniq only:"
    b = a1 + a2
    puts Benchmark.measure { b.uniq }
    

    On my machine (Ubuntu Karmic, Ruby 1.8.7), I get output like this:

    Merge with pipe:
      1.000000   0.030000   1.030000 (  1.020562)
    Merge with concat and uniq:
      1.070000   0.000000   1.070000 (  1.071448)
    Concat only:
      0.010000   0.000000   0.010000 (  0.005888)
    Uniq only:
      0.980000   0.000000   0.980000 (  0.981700)
    

    Which shows that these two techniques are very similar in speed, and that uniq is the larger component of the operation. This makes sense intuitively, being O(n) (at best), whereas simple concatenation is O(1).

    So, if you really want to speed this up, you need to look at how the <=> operator is implemented for the objects in your arrays. I believe that most of the time is being spent comparing objects to ensure inequality between any pair in the final array.

提交回复
热议问题