2016-10-25 12 views
2

のコンマ区切りcpu_ids:"0,2,24"に変換するcpu_ids(3 CPUの場合は0xA00000800000)のバイナリカウントを含むマスクがあります。GoでCPU IDのビットマスク変換

次のGo実装を行った(私はGoスターターである)。それを行うのが最善の方法ですか?特に、バイトバッファーの処理は非効率的です!

package main 

import (
    "fmt" 
    "os" 
    "os/exec" 
) 

func main(){ 
    cpuMap  := "0xA00000800000" 
    cpuIds  = getCpuIds(cpuMap) 
    fmt.Println(cpuIds) 
} 

func getCpuIds(cpuMap string) string { 
    // getting the cpu ids 
    cpu_ids_i, _ := strconv.ParseInt(cpuMap, 0, 64) // int from string 
    cpu_ids_b := strconv.FormatInt(cpu_ids_i, 2) // binary as string 

    var buff bytes.Buffer 
    for i, runeValue := range cpu_ids_b { 
     // take care! go returns code points and not the string  
     if runeValue == '1' { 
      //fmt.Println(bitString, i) 
      buff.WriteString(fmt.Sprintf("%d", i)) 
     } 
     if (i+1 < len(cpu_ids_b)) && (runeValue == '1') { 
      //fmt.Println(bitString) 
      buff.WriteString(string(",")) 
     } 

    } 
    cpuIds := buff.String() 
    // remove last comma 
    cpuIds = cpuIds[:len(cpuIds)-1] 
    //fmt.Println(cpuIds) 
    return cpuIds 
} 

戻り値:

"0,2,24"

+0

サンプルにインポートを追加できますか? 'go doc'を使用しようとすると多くの役に立ちます:) –

答えて

3

あなたがやっていることは、基本的に左からバイナリ表現で"1"年代のインデックスを出力しています右から左へのインデックスカウントを開始する(慣れない)。

バイナリ文字列に変換せずに、ビットマスクとビット演算子を使用して同じ結果を得ることができます。そして、私はフォーマットされた文字列の代わりにインデックスのスライスを返すでしょう、使いやすくなりました。

最下位ビット(右端)が1であるかどうかをテストするには、x&0x01 == 1のようにして、ビット単位で右にビットをシフトします(x >>= 1)。シフト後、右端のビットが「消え」、前の2ビット目が1になるので、同じロジックで再度テストすることができます。数字が0より大きくなるまでループします(つまり、ビットは1ビットです)。

ビット演算の例については、この質問を参照してください:もちろんDifference between some operators "|", "^", "&", "&^". Golang

我々は右端のビットをテストし、右シフトした場合、我々は(あなたが望むものに比べて)ために、ビット(インデックス)を取得インデックスは右から数えられるので、結果を返す前にこれを修正する必要があります。

だから、解決策は次のようになります。コンマはこれは、stringを分離として何らかの理由で結果が必要な場合

[0 2 24] 

func getCpuIds(cpuMap string) (r []int) { 
    ci, err := strconv.ParseInt(cpuMap, 0, 64) 
    if err != nil { 
     panic(err) 
    } 

    count := 0 
    for ; ci > 0; count, ci = count+1, ci>>1 { 
     if ci&0x01 == 1 { 
      r = append(r, count) 
     } 
    } 

    // Indices are from the right, correct it: 
    for i, v := range r { 
     r[i] = count - v - 1 
    } 
    // Result is in reverse order: 
    for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 { 
     r[i], r[j] = r[j], r[i] 
    } 

    return 
} 

出力(Go Playground上でそれを試してみてください)どのようにそれを得ることができます:

buf := &bytes.Buffer{} 
for i, v := range cpuIds { 
    if i > 0 { 
     buf.WriteString(",") 
    } 
    buf.WriteString(strconv.Itoa(v)) 
} 
cpuIdsStr := buf.String() 
fmt.Println(cpuIdsStr) 

出力Go Playground):

0,2,24 
+0

洞察と詳細な例 – PlagTag

関連する問題