Golang vs JavaScript(v8/node.js)映射性能

Golang vs JavaScript(v8/node.js)映射性能,javascript,performance,dictionary,data-structures,go,Javascript,Performance,Dictionary,Data Structures,Go,出于好奇,我编写了一些简单的基准测试,将golang映射的性能与用作映射的JavaScript(v8/node.js)对象进行比较,并对它们的相对性能感到惊讶。JavaScript对象的执行速度似乎是go映射的两倍(甚至包括go的一些次要性能优势) 以下是go实现: //map.go 包干管 输入“fmt” 导入“时间” func elapsedMillis(t0,t1 time.time)浮点64{ n0,n1:=float64(t0.UnixNano()),float64(t1.UnixNa

出于好奇,我编写了一些简单的基准测试,将golang映射的性能与用作映射的JavaScript(v8/node.js)对象进行比较,并对它们的相对性能感到惊讶。JavaScript对象的执行速度似乎是go映射的两倍(甚至包括go的一些次要性能优势)

以下是go实现:

//map.go
包干管
输入“fmt”
导入“时间”
func elapsedMillis(t0,t1 time.time)浮点64{
n0,n1:=float64(t0.UnixNano()),float64(t1.UnixNano())
返回(n1-n0)/1e6
}
func main(){
m:=make(映射[int]int,1000000)
t0:=时间。现在()
对于i:=0;i<1000000;i++{
m[i]=i//Put。
_=m[i]+1//获取、使用、丢弃。
}
t1:=时间。现在()
fmt.Printf(“go:%fms\n”,elapsedMillis(t0,t1))
}
下面是JavaScript:

#/usr/bin/env节点
//map.js
函数elapsedMillis(hrtime0,hrtime1){
var n0=hrtime0[0]*1e9+hrtime0[1];
var n1=hrtime1[0]*1e9+hrtime1[1];
返回(n1-n0)/1e6;
}
var m={};
var t0=process.hrtime();

对于(var i=0;i您的基准测试是合成的,就像任何基准测试一样。只是为了好奇的尝试

for i := 0; i < 1000000; i += 9 {
i:=0;i<1000000;i+=9的
{

在Go实现中。您可能会感到惊讶。

我不确定Go是否在对数字进行哈希运算,我也不确定javascript是否也在进行哈希运算。0…1M之间的连续整数映射基本上是一个数组。将m初始化为1M整数数组,将执行时间减少到2ms。现在使用字符串进行此基准测试,这是一个真正的比较。我不会这样做如果v8的速度也会更快,我也不会感到惊讶。@Not_a_Golfer:是的,我猜go可能会直接使用int键而不是散列键;我想我可以阅读哈希表实现来找到答案。有趣的是,如果我在两种语言中都使用字符串键(使用
s:=strconv.Itoa(I)
var s='''+I
)虽然在js中使用数字键要快得多,但它们的性能大致相同。这里有许多谜团……”JavaScript将整数键转换为字符串属性名-不,不是。即使它们是等价的,引擎也不是这样做的。它很快意识到你正在滥用一个对象作为数组,并将在下面使用一个数组。@Bergi:是的,这可以解释很多(请参阅我对@not_a_Golfer的评论)。看起来这个愚蠢的基准测试可能是对v8引擎的优化部分进行了调整…顺便说一句,在Go中,使用该软件包进行基准测试更容易、更好。嗯,是的,很有趣。增加一个以外的值似乎可以击败我怀疑增加一个的v8优化(例如,使用数组实现而不是哈希表)。Go映射完全按照哈希表实现(没有任何数组)增加一个键,你只是试图用大量冲突来模拟病理数据集。所以你的建议是在JS中执行所有循环步骤,但让我们跳过89%的迭代,并对其进行基准测试?非常有趣的方法,具有非常“令人惊讶”的结果:D
for i := 0; i < 1000000; i += 9 {