ToDo:
http://risky-safety.org/~zinnia/d/2012/02/#20120227-t0-h1-p0 経由で
http://d.hatena.ne.jp/iasija/20091124/1259060817
を見て、 go の方が遅いってのもへんな話かなーとちょっと動かしてみる。
> erlc ring_bench.erl
> time erl +P 200000 -noshell -eval 'io:format("~w\n", [timer:tc(ring_bench, start, [20000, 100, "hello"])]).' -s init stop
{1435773,ok}
erl +P 200000 -noshell -eval -s init stop 1.72s user 0.21s system 75% cpu 2.554 total
> ~/src/go/bin/6g ring_bench.go && ~/src/go/bin/6l ring_bench.6
> time ./6.out 20000 100 hello
20000 100 1.417406
./6.out 20000 100 hello 1.38s user 0.04s system 99% cpu 1.429 total
1435773 ってのはたぶん micro seconds だろう、と考えるとまぁだいたい互角か、ちょっと erlang の方が遅い。この2年の間に go の処理系がちょっと速くなったって感じなのかな。なんか Core 2 Duo E8400 3GHz vs Core i7-2630QM 2GHz というあたりも考えるとそのへんの違いかもしれないけど。
go のコードは log.Exit がなくなってたので log.Fatal に変えて、 Printf の最後に改行文字欲しかったので入れておいた。
ついでに、 make(chan Msg, 1) は make(chan Msg) の方が速そうかなあというのと、最後の stop は自分に帰ってきてないというのを修正してみたり。高速化はそれなりに効いて、
> time ./6.out 20000 100 hello 2012/03/06 01:51:00 OK 20000 100 1.053176 ./6.out 20000 100 hello 1.02s user 0.04s system 99% cpu 1.067 total
とのこと。
--- ring_bench.go 2012-03-06 01:43:53.020232774 +0900
+++ ring_bench2.go 2012-03-06 01:44:09.200232421 +0900
@@ -16,42 +16,47 @@
func main() {
// コマンドライン引数の処理
flag.Parse();
- if flag.NArg() != 3 { log.Exit("invalid argument.") }
+ if flag.NArg() != 3 { log.Fatal("invalid argument.") }
n , err := strconv.Atoi(flag.Arg(0));
- if err != nil { log.Exit("setconv.Atoi:", err) }
+ if err != nil { log.Fatal("setconv.Atoi:", err) }
m , err := strconv.Atoi(flag.Arg(1));
- if err != nil { log.Exit("setconv.Atoi:", err) }
+ if err != nil { log.Fatal("setconv.Atoi:", err) }
str := flag.Arg(2);
ts := time.Nanoseconds(); // 時間計測開始
start(n, m, str);
te := time.Nanoseconds(); // 時間計測終了
- fmt.Printf("%d %d %f", n, m, float64(te - ts) / 1000000000); // N M 秒
+ fmt.Printf("%d %d %f\n", n, m, float64(te - ts) / 1000000000); // N M 秒
}
// メインの処理
func start(n int, m int, str string) {
- nch := make(chan Msg, 1);
- pch := make(chan Msg, 1);
+ nch := make(chan Msg);
+ pch := make(chan Msg);
// リング作り
makeRing(n, nch, pch);
// リングにメッセージを投げる
- nch <- Msg{command:message, str:str};
+ msg := Msg{command:message, str:str};
for i := 0; i < m; i++ {
- msg := <- pch;
nch <- msg;
+ msg = <- pch;
}
nch <- Msg{command:stop}; // リングを壊す
- <- pch; // リングが壊れるのを待つ
+ msg = <- pch; // リングが壊れるのを待つ
+ if msg.command == stop {
+ log.Println("OK")
+ } else {
+ log.Println("???")
+ }
}
func makeRing(n int, nch chan Msg, pch chan Msg) {
- var prevCh chan Msg = nch;
+ prevCh := nch;
for i := 0; i < n-1; i++ {
- nextCh := make(chan Msg, 1);
+ nextCh := make(chan Msg);
go makeNode(nextCh, prevCh);
prevCh = nextCh;
}
(01:51)
| 前 | 2012年 3月 |
次 | ||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
全てリンクフリーです。 コード片は自由に使用していただいて構いません。 その他のものはGPL扱いであればあらゆる使用に関して文句は言いません。 なにかあれば下記メールアドレスへ。