我不知道为什么会出现在我的情况下

问题描述:

JS和围棋之间没有大的性能差异,我只是解决了项目欧拉#12问题,关于除数和三角形数量,一旦进入,一次在JavaScript中。我认为Go中的代码比JS中的代码快得多,因为JS在运行时运行代码并且Go编译代码。我知道构建代码​​并不直接意味着良好的性能,但结果是即使JS中的代码在不同的条件下有时也更快。我不知道为什么会出现在我的情况下

我使用的代码是象下面这样。

https://gist.github.com/noraesae/675e40477e177f9f63f9

我测试了他们在我的MacBook,以及规范是像下面。

处理器:2.6 GHz英特尔酷睿
内存:8 GB 1600 MHz的DDR3

我跑它们与下面的命令。

$ #js
$节点euler12.js

$ #go
$去建立euler12.go
$ ./euler12

难道我做错了什么?如果没有,为什么他们之间没有区别?我还用Python进行了测试,Go和Python之间存在很大差距。提前致谢。

+2

这正是相同的代码,一个被通过转到编译器编译,其他通过的JIT Javascript VM。那么:你为什么期望在合成的人造代码上存在重大差异? – Volker 2014-10-29 14:25:31

+0

非常真实,感谢提及JIT,因为我没有注意到它。虽然,与JavaScript相比,Go是一种低级和静态类型的语言,我认为可能会有一些性能优势。此外,我认为Go可能不需要解释过程,这让我期待Go更快。我想错了吗? – Jun 2014-10-29 16:08:08

+1

尽管代码的外观如何,它并不是相同的代码。具体而言:类型是不同的。一种是在JavaScript情况下隐式处理浮点双精度,Go代码使用'int64'。由于数字类型在JavaScript中是隐含的,因此一些评估人员可以在表面下方切换类型表示,以便它可以使用更便宜的表示法。例如,当V8知道数字不是那么大时,将使用31位小整数。 http://thibaultlaurens.github.io/javascript/2013/04/29/how-the-v8-engine-works/ – dyoo 2014-10-29 17:39:03

非常有趣,我的机器(MacBook Pro的2013年底,酷睿i7 2.3GHz的)上的JS代码比围棋一个快得多:

JS:

time node test.js 
842161320 

real 0m4.437s 
user 0m4.900s 
sys  0m0.150s 

转到:

time GOMAXPROCS=8 ./test 
842161320 

real 0m7.345s 
user 0m7.470s 
sys  0m0.010s 

但是,在Go代码的快速优化之后:

转到:

time GOMAXPROCS=8 ./test 
842161320 

real 0m1.760s 
user 0m11.610s 
sys  0m0.230s 

快速优化我说的(很幼稚):并行化计算:

package main 

import (
     "fmt" 
     "os" 
     "runtime" 
) 

func numberOfDevisor(n int64) int64 { 
     var result int64 

     var i int64 = 1 
     for true { 
       if n%i == 0 { 
         opposite := n/i 
         if opposite == i { 
           result++ 
           return result 
         } else if opposite > i { 
           result += 2 
         } else { 
           return result 
         } 
       } 
       i++ 
     } 
     return result 
} 

func main() { 
     var acc int64 
     var i int64 = 1 

     maxRoutines := runtime.NumCPU() 
     c := make(chan struct{}, maxRoutines) 
     for i := 0; i < maxRoutines; i++ { 
       c <- struct{}{} 
     } 
     for true { 
       <-c 
       acc += i 
       go func(acc int64) { 
         defer func() { c <- struct{}{} }() 
         if numberOfDevisor(acc) > 1000 { 
           fmt.Println(acc) 
           os.Exit(0) 
         } 
       }(acc) 
       i++ 
     } 
}