勉強の為に引用しました。
http://blog.toshimaru.net/ruby-vs-go/
05 Mar 2015 ruby go
Rubyで書いたコードがGoで書いたらどれくらい早くなるかを検証したくてやってみた。画像ファイルをダウンロードするだけの単純な処理での比較。(複雑な処理になるとまた全然違ってくると思います)
Rubyの場合
イメージを100個ダウンロードするコードをサンプルにやってみました。
直列にダウンロード
何も考えず1つ1つダウンロードするコード。
require 'open-uri'
(1..100).each do |i|
open("./images/#{i}.png", 'wb') do |f|
f.write open("http://dummyimage.com/600x400").read
end
end
$ time ruby no_thread.rb
ruby no_thread.rb 0.25s user 0.10s system 1% cpu 29.813 total
約30秒。遅い。そしてCPUコストは低い。
Threadで並行ダウンロード
Thread使って並行に処理してみる。
require 'open-uri'
thr = []
(1..100).each do |i|
thr << Thread.new do
open("./images/#{i}.png", 'wb') do |f|
f.write open("http://dummyimage.com/600x400").read
end
end
end
thr.map(&:join)
$ time ruby thread.rb
ruby thread.rb 0.20s user 0.10s system 27% cpu 1.105 total
1.1秒。劇的な改善。CPUは30%くらい使ってる。
Goの場合
Goで書きなおしてみる。
こちらを参考に書いてみた。
package main
import (
"fmt"
"io"
"net/http"
"os"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
var url string = "http://dummyimage.com/600x400"
//ファイルを開く
file, err := os.Create("images/" + fmt.Sprint(i) + ".png")
if err != nil {
panic(err)
}
go func() {
response, err := http.Get(url)
if err != nil {
panic(err)
}
//レスポンスのボディを閉じる関数の遅延実行指定
defer response.Body.Close()
//fmt.Println("status:", response.Status)
//ファイルを閉じる関数の遅延実行指定
defer file.Close()
//レスポンスのボディから読み込みつつファイルに書き出す。
io.Copy(file, response.Body)
wg.Done()
}()
}
wg.Wait()
}
Go run で実行
コンパイルせずにgo runで実行してみる。
$ time go run sample.go
go run sample.go 0.50s user 0.21s system 50% cpu 1.413 total
1.4秒。Thread使ったRubyのコードと同じくらい。
Go build :arrow_right: Run
buildして実行する。
$ go build sample.go
$ time ./sample
./sample 0.06s user 0.07s system 16% cpu 0.789 total
約0.8秒。Rubyで書いたコードの3/4の時間で完了した。
今回は単純な処理なのでRubyとGoの間で大きな差は生まれなかったものの、比較するロジックが複雑化すればするほどGoのパフォーマンスの良さがガッツリと効いてきそう。CPUコストがRubyより半分程度に済んでいるところもナイス。
【番外編】Shell Script で実行
for i in `seq 1 100`; do
wget --background --quiet "http://dummyimage.com/600x400" -O images/$i.png > /dev/null
done
$ time bash bash_script.bash
bash bash_script.bash 0.15s user 0.24s system 72% cpu 0.547 total
約0.5秒。はやい。 :astonished:
CPUも超使ってる。
2016年12月31日土曜日
RubyとGolang で並行処理のパフォーマンス比較してみた。(引用日2016年12月31日)
19:41
No comments
0 コメント:
コメントを投稿