我一直在处理一些必须转换为 UTF-8 的大文件,因为这些文件是巨大的传统工具,如 iconv 无法工作。所以我决定用 Go 编写自己的工具,但是我注意到这种编码转换在 Go 中非常慢。这是我的代码:
package main
import (
"fmt"
"io"
"log"
"os"
"golang.org/x/text/encoding/charmap"
)
func main() {
if len(os.Args) != 3 {
fmt.Fprintf(os.Stderr, "usage:\n\t%s [input] [output]\n", os.Args[0])
os.Exit(1)
}
f, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
out, err := os.Create(os.Args[2])
if err != nil {
log.Fatal(err)
}
r := charmap.ISO8859_1.NewDecoder().Reader(f)
buf := make([]byte, 1048576)
io.CopyBuffer(out, r, buf)
out.Close()
f.Close()
}
Python 中的类似代码性能更高:
import codecs
BLOCKSIZE = 1048576 # or some other, desired size in bytes
with codecs.open("FRWAC-01.xml", "r", "latin_1") as sourceFile:
with codecs.open("FRWAC-01-utf8.xml", "w", "utf-8") as targetFile:
while True:
contents = sourceFile.read(BLOCKSIZE)
if not contents:
break
targetFile.write(contents)
我确信我的 Go 代码会快得多,因为 Go 中的一般 I/O 很快,但事实证明它比 Python 代码慢得多。有没有办法改进 Go 程序?
最佳答案
这里的问题是您没有在两种情况下比较相同的代码。此外,Go 中的 IO 速度与 python 没有显着差异,因为它们进行相同的系统调用。
在python版本中,文件默认是缓冲的。在 Go 版本中,当您将 io.CopyBuffer
与 1048576
字节缓冲区一起使用时,解码器将进行任何大小的 Read
调用它需要直接在未缓冲的文件上。
用 bufio
包装文件 IO 将产生类似的结果。
inFile, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
defer inFile.Close()
outFile, err := os.Create(os.Args[2])
if err != nil {
log.Fatal(err)
}
defer outFile.Close()
in := bufio.NewReaderSize(inFile, 1<<20)
out := bufio.NewWriterSize(outFile, 1<<20)
defer out.Flush()
r := charmap.ISO8859_1.NewDecoder().Reader(in)
if _, err := io.Copy(out, r); err != nil {
log.Fatal(err)
}
关于python - Go中如何改进文件编码转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50860670/