goroutine を使ってみた
Go 翻訳プロジェクトが立ち上がったようですね。チュートリアルのかなりの部分がもう訳されてます。
http://go.shibu.jp/
遊んでるうちに、将来は C に取って代わりそうだなという気がしてきました。
昨日のコードの goroutine 版が動きました。まだ goroutine がどういうものかさっぱりわからないので、使い方が間違ってる可能性大ですが。
ちょっと新人いじめがすぎました。遅いです。いや、使い方が間違ってるほうが大きいかもしれないけど。
(追記) うわさの runtime.GOMAXPROCS つけたらものすごく速くなった!使えるかもと思った。コードは差し替えておきます。
4CPU割り当ててやってみたらむしろ遅くなったw みんな並列じゃ苦労してるんだねw
以下、コード
package main import ( "math"; "fmt"; "os"; "runtime"; "container/vector"; ) const ( K = 4; N = 2; ) const channelBufferNum = 2048 type DeBruijnSeq struct { k, n, max int; out chan *vector.IntVector; // for output count chan int; } type DeBruijnSeqResult struct { ch chan *vector.IntVector; result chan *vector.Vector; } func Init(k, n int) (d *DeBruijnSeq, result *DeBruijnSeqResult, ok bool) { if k < 2 || 10 < k { return nil, nil, false } if n < 1 { return nil, nil, false } max := math.Pow(float64(k), float64(n)); if float64(0x7FFFFFFF) < max { return nil, nil, false } out, result := startOutputServer(); count := make(chan int, channelBufferNum); return &DeBruijnSeq{k, n, int(max), out, count}, result, true; } func (d *DeBruijnSeq) Search() { a := vector.NewIntVector(d.n); for i := 0; i < d.n; i++ { a.Set(i, 0) } go d.searchCore(a); } func (d *DeBruijnSeq) searchCore(a *vector.IntVector) { // 重複判定 if !d.isUnique(a) { d.count <- -1; return; } // 完成判定 if d.isComplete(a) { //fmt.Println( " comp! " ); d.out <- a; d.count <- -1; return; } // 次の反復へ for i := 0; i < d.k; i++ { d.count <- 1; b := vector.NewIntVector(0); b.AppendVector(a); // copy b.Push(i); go d.searchCore(b); } d.count <- -1; } func (d *DeBruijnSeq) isUnique(a *vector.IntVector) bool { if a.Vector.Len() <= d.n { return true } pos := a.Vector.Len() - d.n; for i := 0; i < pos; i++ { if sequenceEqual(a, i, pos, d.n) { return false } } return true; } func sequenceEqual(v *vector.IntVector, a, b, len int) bool { for i := 0; i < len; i++ { if v.At(a) != v.At(b) { return false } a++; b++; } return true; } func (d *DeBruijnSeq) isComplete(a *vector.IntVector) bool { if a.Vector.Len() != d.max { return false } b := vector.NewIntVector(0); b.AppendVector(a); // copy for i := 0; i < d.n-1; i++ { b.Push(b.At(i)); if !d.isUnique(b) { return false } } return true; } func startOutputServer() (chan *vector.IntVector, *DeBruijnSeqResult) { out := make(chan *vector.IntVector, channelBufferNum); result := make(chan *vector.Vector, 2); go output(out, result); return out, &DeBruijnSeqResult{out, result}; } func output(in chan *vector.IntVector, out chan *vector.Vector) { v := vector.New(0); for !closed(in) { if data := <- in; data != nil { //fmt.Println( data ); v.Push(data); } } out <- v; } func main() { runtime.GOMAXPROCS(2); d, result, ok := Init(K, N); if !ok { os.Exit(1) } d.Search(); for numOfGor := 1; numOfGor != 0; { numOfGor += <-d.count } close(result.ch); n := <-result.result; fmt.Println(n.Len()); }