Like Max, my strong suspicion was that Go's slowness was due to poor I / O performance. I tested this hypothesis:
package main import "fmt" import "os" import "time" func main(){ now := time.Now() input,_ := os.Open("testing/test_cases.txt") defer input.Close() output,_ := os.Create("testing/Goutput.txt") defer output.Close() var ncases int var p float64 fmt.Fscanf(input,"%d",&ncases) fmt.Println("Opened files in ", time.Since(now), "seconds") now = time.Now() cases := make([]float64, ncases) fmt.Println("Made array in ", time.Since(now), "seconds") now = time.Now() for i := 0; i < ncases; i++ { fmt.Fscanf(input,"%f",&cases[i]) } fmt.Println("Read data in ", time.Since(now), "seconds") now = time.Now() for i := 0; i < ncases; i++ { p = cases[i] if p >= 0.5 { cases[i] = 10000 * (1-p) * (2*p-1) + 10000 } else { cases[i] = p*(1-2*p)*10000 + 10000 } } fmt.Println("Processed data in ", time.Since(now), "seconds") now = time.Now() for i := 0; i < ncases; i++ { fmt.Fprintln(output, cases[i]) } fmt.Println("Output processed data in ", time.Since(now), "seconds") }
Running it, he made this conclusion:
Opened files in 2.011228ms seconds
Made array in 109.904us seconds
Read data in 4.524544608s seconds
Processed data in 10.083329ms seconds
Output processed data in 1.703542918s seconds
So, it looks like on my machine all the math comes up after about 10 ms, but I / O is slow, confirming the hypothesis. As Yann noted in the comments, there are more likely to be faster options than fmt .
Update: For example, wrapping input and output with bufio "Readers and Writers":
binput := bufio.NewReader(input) boutput := bufio.NewWriter(output)
and using binput and boutput for buffered I / O, your original version runs on my machine in 2.1 seconds, which is slightly faster than Python 2.7.
Update 2: I noticed that I get different results by simply switching to buffered I / O.
Turns out you also need to tweak the format strings to include \n , as in version C. I think this is actually more correct anyway, but it looks like you can leave with it until you are buffered.
It is also important Flush() your buffer output, which I made, but not mentioned earlier.
Here is my full buffer solution:
package main import "fmt" import "os" import "bufio" import "time" func main(){ now := time.Now() nbinput, _ := os.Open("testing/test_cases.txt") defer nbinput.Close() nboutput, _ := os.Create("testing/Goutput.txt") defer nboutput.Close() binput := bufio.NewReader(nbinput) boutput := bufio.NewWriter(nboutput) var ncases int var gain, p float64 fmt.Fscanf(binput,"%d\n",&ncases) for i := 0; i < ncases; i++ { fmt.Fscanf(binput, "%f\n", &p) if p >= 0.5 { gain = 10000 * (1-p) * (2*p -1) } else { gain = p*(1-2*p)*10000 } fmt.Fprintln(boutput, gain+10000) } boutput.Flush() fmt.Println("Took ", time.Since(now), "seconds") }