6

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?

4
  • 2
    Do you use bufio? Why fmt.Scanf and not just strconv.Atoi? Post the code, there's not enough info. Commented May 1, 2015 at 8:08
  • 1
    @Ainar-G what code are you looking for. All I do reading a bunch of integers from stdin. And I clearly stated how I have done it (with fmt.Scanf which means that no, I have not used bufio). Why not just strconv.Atoi because I found how to read an integer in the answer on stackoverflow and it was telling to use scanf. I think it is more than enough info to understand what I am talking about. Commented May 1, 2015 at 8:12
  • @Salvador Dali Just curious, how you provide 10^5 integers to stdin? Can you do that at 2.5 seconds? Commented May 1, 2015 at 10:19
  • @Uvelichitel as I wrote, I am using Go to solve programming competitions. In all of them you receive input on stdin and have to write your answer in stdout Commented May 1, 2015 at 18:44

1 Answer 1

5

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?

Sign up to request clarification or add additional context in comments.

4 Comments

do you have any idea why scanf is so slow (it is kind of strange to have a function which does something super inefficient when there is an efficient approach to do something. P.S. thanks, I will try your answer
Well my code assumes that input is an integer. Scanf has multiple placeholders and is more flexible. This flexibility should come at a performance cost (more branches).
if you look at the source code golang.org/src/fmt/scan.go?s=3461:3523#L74, and go through the function calls, the critical inner function seems to be scanOne (line 930) which has lots of case branches
@metakeule To see output why Ctrl + D has to be pressed ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.