我怎样才能有效地从Go中的stdin读取数字(或者为什么fmt.Scanf效率太低)

Sal*_*ali 5 go

我开始在go中进行编程竞赛(只是为了学习语言)并且我惊讶地发现了

var T int
fmt.Scanf("%d", &T)
Run Code Online (Sandbox Code Playgroud)

是难以想象的慢.多慢?要读取10 ^ 5个整数,它需要2.5秒(相比之下python在0.8秒内完成).

那么,为什么它这么慢,我应该如何正确读取int,uint64float64

met*_*ule 5

如果你只有整数作为输入,这应该更快(虽然没有测试)

package main

import (
    "io/ioutil"
    "log"
    "os"
    "strconv"
)

func read() (int64, error) {
    b, err := ioutil.ReadAll(os.Stdin)
    if err != nil {
        return 0, err
    }

    // use strconv.ParseUint and strconv.ParseFloat in a similar way
    return strconv.ParseInt(string(b[:len(b)-1]), 10, 0)
}

func main() {
    i, err := read()
    if err != nil {
        log.Fatal(err)
    }

    println(i)
}
Run Code Online (Sandbox Code Playgroud)

像这样运行它

echo 123 | go run main.go
Run Code Online (Sandbox Code Playgroud)

对于交互式输入,您可能希望使用bufio.NewReader,请参阅如何从控制台行读取输入?

  • 如果你查看源代码http://golang.org/src/fmt/scan.go?s=3461:3523#L74,并进行函数调用,那么关键的内部函数似乎是scanOne(第930行)它有很多案例分支 (5认同)