IPアドレスをソートする (性能比較編)
前回の記事で、IPアドレスのソートについて書きました。
今回はその続きで、takiuchiさんに教えてもらったものや、自分で書いたものの性能比較をしようと思います。
まず、前回の記事&コメントでどのようなソート方法があったかというと、
①自分で書いたソート(以下, my_sort_1)
ruby>>
ip_addrs.sort_by{|a| a.split(".").map{|i| "%3d" % i.to_i}}
<<ruby
②自分で書いたソート・改(以下, my_sort_2)
ruby>>
ip_addrs.sort_by{|a| a.split(".").map{|i| i.to_i}}
<<ruby
③takiuchiさんに教えていただいたソート(以下, takiuchi_sort)
ruby>>
ip_addrs.sort_by{|i| Socket.sockaddr_in nil, i}
<<ruby
の3つです。
これらについて、ベンチマークをとってみます。
ソートする対象としては、世界の国別 IPv4 アドレス割り当てリストを使いました。
まず、下準備として、上記リストには、サブネットマスク版と、CIDR表記版があるので、ここからIPアドレスのみを抽出し、Array型のオブジェクトに格納ておきます(このオブジェクトをip_addrsとする)。
全部で、51814のIPアドレスがあるらしいです。
そして、ベンチマークをとってみます。
-コード
ruby>>
require 'benchmark'
Benchmark.bm do |x|
x.report("my_sort_1 :"){ ip_addrs.sort_by{|a| a.split(".").map{|i| "%3d" % i.to_i}}}
x.report("my_sort_2 :"){ ip_addrs.sort_by{|a| a.split(".").map{|i| i.to_i}}}
x.report("takiuchi_sort:"){ ip_addrs.sort_by{|i| Socket.sockaddr_in nil, i}}
end
<<ruby
-結果
ruby>>
user system total real
my_sort_1 : 3.860000 1.160000 5.020000 ( 5.017623)
my_sort_2 : 2.170000 0.650000 2.820000 ( 2.819594)
takiuchi_sort: 0.690000 0.180000 0.870000 ( 0.864372)
<<ruby
takiuchiさんに教えていただいたソートが圧倒的に速いですね!!
ここまで差がでるとは、正直思っていなかった。
自分で書いたmy_sort_1とmy_sort2でもかなりの差がみられました。
まぁ、my_sort_1のほうは無駄が多いですしね・・・。
こんな感じで、結論としては、
takiuchiさんの、
ruby>>
ip_addrs.sort_by{|i| Socket.sockaddr_in nil, i}
<<ruby
がベンチマーク的に優秀で、コードの見た目もシンプルでかなり良さげです!!
他に「こんな方法のソートがあるよ!」というのがあれば、教えていただけると嬉しいです!