Rubyで配列内の重複する値を抽出する方法

こちらの記事の Rubyで配列から重複している値を抽出するのを考えてみた。
http://d.hatena.ne.jp/kiyo560808/20110801/1312196444

a = [1, 2, 3, 4, 5, 6, 5, 4]
a.uniq.reject{|i| a.index(i) == a.rindex(i)}
#=> [4, 5]

もしくは

a = [1, 2, 3, 4, 5, 6, 5, 4]
a.uniq.reject{|i| a.count(i) == 1}
#=> [4, 5]

こんな感じか?

ふとパフォーマンスが気になったので調べてみた。

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'benchmark'

a = (1..10000).to_a
a += [1, 10000]

Benchmark.bm do |x|
  x.report("Array#index:") do
    a.uniq.reject{|i| a.index(i) == a.rindex(i)}
  end

  x.report("Array#count:") do
    a.uniq.reject{|i| a.count(i) == 1}
  end

  x.report("using Hash:") do
    h = {}
    a.each do |i|
      h[i] ||= 0
      h[i] += 1
    end

    r = []
    a.uniq.each do |i|
      r << i if h[i] > 1
    end
  end
end
      user     system      total        real
Array#index: 12.430000   0.010000  12.440000 ( 12.461251)
Array#count: 11.930000   0.000000  11.930000 ( 11.967026)
using Hash:  0.020000   0.010000   0.030000 (  0.029133)

結果、泥臭く書いたのがダントツで速いとか。


追記メモ
1行でやるなら

a.inject(Hash.new(0)){|h, i| h[i] += 1; h }.reject{|k, v| v <= 1 }.keys