Last active
January 2, 2016 01:38
-
-
Save ohkawa/dcb5b768caaf1024f39a to your computer and use it in GitHub Desktop.
Goでバケットソートアルゴリズム(ビット列を使用) ref: http://qiita.com/ohkawa/items/269507985b3ae10cbff9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bufio" | |
| "fmt" | |
| "log" | |
| "math" | |
| "os" | |
| "strconv" | |
| "time" | |
| ) | |
| // エラー共通処理 | |
| func failOnError(err error) { | |
| if err != nil { | |
| log.Fatal("Error:", err) | |
| } | |
| } | |
| // 整数をbit配列で表した場合の位置(xバイト目のy番目のbit)を返却する | |
| func getAddress(num int) (uint, uint) { | |
| return uint(num / 8), uint(num % 8) | |
| } | |
| // ファイルから整数を読み取り、 | |
| // 入力ファイルに整数iがあればi番目のビットを1(オン)にしたByte配列を返す | |
| func fromFile(filePath string) []byte { | |
| f, err := os.Open(filePath) | |
| failOnError(err) | |
| defer f.Close() | |
| // 最大値が判明している場合は最初からその分メモリを確保すれば良い | |
| // 最大値が不明な場合はいちいちメモリを確保し直す必要がある?=逆に遅くなる可能性も | |
| size := math.Pow10(7)/8 + 1 | |
| lines := make([]byte, int(size)) | |
| scanner := bufio.NewScanner(f) | |
| for scanner.Scan() { | |
| num, _ := strconv.Atoi(scanner.Text()) | |
| index, order := getAddress(num) | |
| x := 1 << order | |
| b := lines[index] | |
| lines[index] = b | byte(x) | |
| } | |
| if err := scanner.Err(); err != nil { | |
| failOnError(err) | |
| } | |
| return lines | |
| } | |
| // 整数iをi番目のビットを1(オン)にすることで表現したByte配列を、 | |
| // 該当する整数に戻して出力する | |
| func writeByteList(path string, list []byte) { | |
| f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) | |
| failOnError(err) | |
| defer f.Close() | |
| var writer *bufio.Writer | |
| writer = bufio.NewWriter(f) | |
| index := 0 | |
| for _, b := range list { | |
| for order := 0; order < 8; order++ { | |
| x := 1 << uint(order) | |
| ret := b & byte(x) | |
| if ret > 0 { | |
| writer.WriteString(strconv.Itoa(index) + "\n") | |
| } | |
| index++ | |
| } | |
| } | |
| writer.Flush() | |
| } | |
| func main() { | |
| start := time.Now() // 処理時間 計測開始 | |
| bytes := fromFile("/var/tmp/sample.csv") | |
| writeByteList("/var/tmp/output2.csv", bytes) | |
| fmt.Println(time.Since(start)) // 処理時間 計測完了 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bufio" | |
| "fmt" | |
| "log" | |
| "os" | |
| "sort" | |
| "strconv" | |
| "time" | |
| ) | |
| // エラー共通処理 | |
| func failOnError(err error) { | |
| if err != nil { | |
| log.Fatal("Error:", err) | |
| } | |
| } | |
| // ファイルから整数を読み取りint配列を返す | |
| func fromFile(filePath string) []int { | |
| f, err := os.Open(filePath) | |
| failOnError(err) | |
| defer f.Close() | |
| lines := make([]int, 0) | |
| scanner := bufio.NewScanner(f) | |
| for scanner.Scan() { | |
| num, _ := strconv.Atoi(scanner.Text()) | |
| lines = append(lines, num) | |
| } | |
| if err := scanner.Err(); err != nil { | |
| failOnError(err) | |
| } | |
| return lines | |
| } | |
| // int配列を\n区切りでファイル出力する | |
| func writeIntList(path string, list []int) { | |
| f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) | |
| failOnError(err) | |
| defer f.Close() | |
| var writer *bufio.Writer | |
| writer = bufio.NewWriter(f) | |
| for _, v := range list { | |
| writer.WriteString(strconv.Itoa(v) + "\n") | |
| } | |
| writer.Flush() | |
| } | |
| func main() { | |
| start := time.Now() // 処理時間 計測開始 | |
| lines := fromFile("/var/tmp/sample.csv") | |
| sort.Sort(sort.IntSlice(lines)) // Int配列の標準ソートを実施 | |
| writeIntList("/var/tmp/output.csv", lines) | |
| fmt.Println(time.Since(start)) // 処理時間 計測完了 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment