2015-05-01 4 views
5

Ich begann Programmierung Wettbewerbe in gehen zu tun (nur die Sprache zu lernen) und zu meiner Überraschung festgestellt, dasswie kann ich von stdin in Go effizient Zahlen lesen (oder warum fmt.Scanf so ineffizient ist)

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

ist unvorstellbar langsam. Wie langsam? Um read 10^5 integers dauert es 2,5 Sekunden (im Vergleich Python macht es in 0,8 Sekunden).

Also warum ist es so langsam und wie sollte ich richtig lesen int, uint64 und float64?

+2

Verwenden Sie 'bufio'? Warum 'fmt.Scanf' und nicht nur' strconv.Atoi'? Sende den Code, es gibt nicht genug Informationen. –

+1

@ Ainar-G welchen Code suchen Sie. Ich lese nur eine ganze Reihe von Ganzzahlen von stdin. Und ich habe klar gesagt, wie ich es gemacht habe (mit 'fmt.Scanf' was bedeutet, dass nein, ich habe' bufio' nicht benutzt). Warum nicht einfach "strconv.Atoi", weil ich herausgefunden habe, wie man in der Antwort auf stackoverflow eine ganze Zahl liest und es scanf verwendet. Ich denke, es sind mehr als genug Informationen, um zu verstehen, wovon ich spreche. –

+0

@Salvador Dali Nur neugierig, wie Sie 10^5 ganze Zahlen zu stdin liefern? Kannst du das bei 2,5 Sekunden tun? – Uvelichitel

Antwort

5

Wenn Sie nur die ganze Zahl als Eingabe haben, sollte dies schneller sein (allerdings nicht getestet)

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) 
} 

laufen sie wie diese

echo 123 | go run main.go 

für interaktive Eingabe, möchten Sie vielleicht bufio verwenden .NewReader, siehe How to read input from console line?

+1

haben Sie irgendeine Idee, warum scanf so langsam ist (es ist irgendwie komisch, eine Funktion zu haben, die etwas sehr ineffizientes tut, wenn es gibt ein effizienter Ansatz, um etwas zu tun PS Danke, ich werde Ihre Antwort versuchen –

+1

Nun mein Code geht davon aus, dass Eingabe ist eine ganze Zahl.Scanf hat mehrere Platzhalter und ist flexibler.Diese Flexibilität sollte zu einer Leistung Kosten kommen (mehr Filialen). – metakeule

+5

if Sie schauen sich den Quellcode http://golang.org/src/fmt/scan.go?s=3461:3523#L74 an und gehen durch die Funktionsaufrufe, die kritische innere Funktion scheint scanOne (Zeile 930) zu sein hat viele Fall Zweige – metakeule

Verwandte Themen