Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I efficiently read numbers from stdin in Go (or why fmt.Scanf is so inefficient)

Tags:

go

I started to do programming contests in go (just to learn the language) and to my surprise found that

var T int
fmt.Scanf("%d", &T)

is unimaginably slow. How slow? To read 10^5 integers it take me 2.5 seconds (in comparison python does it in 0.8 secs).

So why is it so slow and how should I properly read int, uint64 and float64?

like image 341
Salvador Dali Avatar asked May 01 '15 08:05

Salvador Dali


1 Answers

If you have only the integer as input, this should be faster (not tested though)

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 it like this

echo 123 | go run main.go

for interactive input, you might want to use bufio.NewReader, see How to read input from console line?

like image 61
metakeule Avatar answered Nov 14 '22 14:11

metakeule