douzhi2012 2016-01-20 17:30
浏览 111

使用io.Writer时,避免在golang中分配过多的内存

I am working on a command line tool in Go called redis-mass that converts a bunch of redis commands into redis protocol format.

The first step was to port the node.js version, almost literally to Go. I used ioutil.ReadFile(inputFileName) to get a string version of the file and then returned an encoded string as output.

When I ran this on a file with 2,000,000 redis commands, it took about 8 seconds, compared to about 16 seconds with the node version. I guessed that the reason it was only twice as fast was because it was reading the whole file into memory first, so I changed my encoding function to accept a pair (raw io.Reader, enc io.Writer), and it looks like this:

func EncodeStream(raw io.Reader, enc io.Writer) {
    var args []string
    var length int

    scanner := bufio.NewScanner(raw)

    for scanner.Scan() {
            command := strings.TrimSpace(scanner.Text())
            args = parse(command)
            length = len(args)
            if length > 0 {
                    io.WriteString(enc, fmt.Sprintf("*%d
", length))
                    for _, arg := range args {
                            io.WriteString(enc, fmt.Sprintf("$%d
%s
", len(arg), arg))
                    }
            }
    }
}

However, this took 12 seconds on the 2 million line file, so I used github.com/pkg/profile to see how it was using memory, and it looks like the number of memory allocations is huge:

# Alloc = 3162912
# TotalAlloc = 1248612816
# Mallocs = 46001048
# HeapAlloc = 3162912

Can I constrain the io.Writer to use a fixed sized buffer and avoid all those allocations?

More generally, how can I avoid excessive allocations in this method? Here's the full source for more context

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
    • ¥100 为什么这个恒流源电路不能恒流?
    • ¥15 有偿求跨组件数据流路径图
    • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
    • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
    • ¥15 CSAPPattacklab
    • ¥15 一直显示正在等待HID—ISP
    • ¥15 Python turtle 画图
    • ¥15 stm32开发clion时遇到的编译问题
    • ¥15 lna设计 源简并电感型共源放大器