golangでも同じことをやってみた
c#でのcp932で化けてしまう一部キャラクタを変換するやつ。それをgoで書いてみたのだけど……。なんだろ、遅い。正規表現は他言語と同じく遅いようで、RegexpではなくReplacer使えーとかそこらへんは考慮して書いたのだが。stopwatchの精度もスリープで確認したりなんだりで問題なさそう。未使用メソッドがあったり、処理の1,2,3を順にループさせたりするとどんどん遅くなる(なので未使用~についてはコメントアウトしてる)のが謎い。
👺 < 処理が遅い!
4826 // -> goでのこのミリセカンド表記はc#版のほうでいうと
00:00:04.0826 // -> これと同値
最終結果は同じだが、文字化け(マッピングできないキャラ)が来るとそこで試合終了っぽい。
package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
"golang.org/x/text/encoding/japanese"
"golang.org/x/text/transform"
)
// ループの外でReplacerを持つようにした
var rep *strings.Replacer
func main() {
fmt.Println("start")
// ファイル読み込み
list := getFileData()
/*list2 := make([]string, len(list))
copy(list2, list)
list3 := make([]string, len(list))
copy(list3, list)*/
// 処理
start1 := time.Now()
// ループの外でReplacerを持つようにした
rep = strings.NewReplacer("〜", "~", "−", "-", "¢", "¢", "£", "£", "¬", "¬", "—", "―", "‖", "∥")
for i := 0; i < 1000000; i++ {
replaceUnmappingChars1(list)
}
stop1 := time.Now()
fmt.Println(stop1.Sub(start1).Milliseconds())
// ファイル書き込み
outputFile(list)
fmt.Println("end")
}
// replace unmapping chars3 -> 8293
/*func replaceUnmappingChars3(list []string) {
for i, str := range list {
sl := strings.Split(str, "")
length := len(sl)
var rep string
for j := 0; j < length; j++ {
if sl[j] == "〜" {
rep += "~"
} else if sl[j] == "−" {
rep += "-"
} else if sl[j] == "¢" {
rep += "¢"
} else if sl[j] == "£" {
rep += "£"
} else if sl[j] == "¬" {
rep += "¬"
} else if sl[j] == "—" {
rep += "―"
} else if sl[j] == "‖" {
rep += "∥"
} else {
rep += sl[j]
}
}
list[i] = rep
}
}*/
// replace unmapping chars2 -> 100万回 9946
/*func replaceUnmappingChars2(list []string) {
for i, str := range list {
var rep string
for _, c := range str {
if string(c) == "〜" {
rep += "~"
} else if string(c) == "−" {
rep += "-"
} else if string(c) == "¢" {
rep += "¢"
} else if string(c) == "£" {
rep += "£"
} else if string(c) == "¬" {
rep += "¬"
} else if string(c) == "—" {
rep += "―"
} else if string(c) == "‖" {
rep += "∥"
} else {
rep += string(c)
}
}
list[i] = rep
}
}*/
// replace unmapping chars -> 100万回 4826
func replaceUnmappingChars1(list []string) {
for i, data := range list {
//rep := strings.NewReplacer("〜", "~", "−", "-", "¢", "¢", "£", "£", "¬", "¬", "—", "―", "‖", "∥")
list[i] = rep.Replace(data)
}
}
// GetFileData return list
func getFileData() []string {
// file open
file, err := os.Open("./source.txt")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close() // c#でのusing - disposeみたいな? todo:あとでもっとよく調べる
// file read
var data []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
data = append(data, scanner.Text())
}
if err := scanner.Err(); err != nil { // どうやったらここに来るんだ?
fmt.Println(err)
os.Exit(1)
}
return data
}
// outputFile
func outputFile(list []string) {
// file create todo:上書きっぽい(あとでよく見る)
file, err := os.Create("./destination_sjis_fix.txt")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
// data write
writer := bufio.NewWriter(transform.NewWriter(file, japanese.ShiftJIS.NewEncoder()))
for _, data := range list {
_, err := writer.WriteString(data + "\n") // やっぱり普通はここで変換するよね(c#でも書いたのでこっちにも)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
writer.Flush() // buf(debuggerでみた)の中にWriteStringで溜めてFlushで一気に書くっぽい
}
なんか根本的にミスってるのかなー。わからん。ベンチマークメソッド?みたいなのがあるからそっちでやらないとダメなのかなー。