Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in golang, is there any performance difference between maps initialized using make vs {}

Tags:

performance

go

as we know there are two ways to initialize a map (as listed below). I'm wondering if there is any performance difference between the two approaches.

var myMap map[string]int

then

myMap = map[string]int{}

vs

myMap = make(map[string]int)
like image 299
srini Avatar asked Jul 11 '16 20:07

srini


2 Answers

On my machine they appear to be about equivalent.

You can easily make a benchmark test to compare. For example:

package bench

import "testing"

var result map[string]int

func BenchmarkMakeLiteral(b *testing.B) {
        var m map[string]int
        for n := 0; n < b.N; n++ {
                m = InitMapLiteral()
        }
        result = m
}

func BenchmarkMakeMake(b *testing.B) {
        var m map[string]int
        for n := 0; n < b.N; n++ {
                m = InitMapMake()
        }
        result = m
}

func InitMapLiteral() map[string]int {
        return map[string]int{}
}

func InitMapMake() map[string]int {
        return make(map[string]int)
}

Which on 3 different runs yielded results that are close enough to be insignificant:

First Run

$ go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkMakeLiteral-8  10000000               160 ns/op
BenchmarkMakeMake-8     10000000               171 ns/op
ok      github.com/johnweldon/bench     3.664s

Second Run

$ go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkMakeLiteral-8  10000000               182 ns/op
BenchmarkMakeMake-8     10000000               173 ns/op
ok      github.com/johnweldon/bench     3.945s

Third Run

$ go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkMakeLiteral-8  10000000               170 ns/op
BenchmarkMakeMake-8     10000000               170 ns/op
ok      github.com/johnweldon/bench     3.751s
like image 69
John Weldon Avatar answered Nov 15 '22 03:11

John Weldon


When allocating empty maps there is no difference but with make you can pass second parameter to pre-allocate space in map. This will save a lot of reallocations when maps are being populated.

Benchmarks

package maps

import "testing"

const SIZE = 10000

func fill(m map[int]bool, size int) {
    for i := 0; i < size; i++ {
        m[i] = true
    }
}

func BenchmarkEmpty(b *testing.B) {
    for n := 0; n < b.N; n++ {
        m := make(map[int]bool)
        fill(m, SIZE)
    }
}

func BenchmarkAllocated(b *testing.B) {
    for n := 0; n < b.N; n++ {
        m := make(map[int]bool, 2*SIZE)
        fill(m, SIZE)
    }
}

Results

go test -benchmem -bench .
BenchmarkEmpty-8             500       2988680 ns/op      431848 B/op        625 allocs/op
BenchmarkAllocated-8        1000       1618251 ns/op      360949 B/op         11 allocs/op
like image 22
Grzegorz Żur Avatar answered Nov 15 '22 05:11

Grzegorz Żur