In general, a good way to answer questions like this is to inspect an 
assembly listing for the code. This is what I compiled:

$ cat foo.go
package foo

import (
"fmt"
)

type Person struct {
Name  string
Likes []string
}

func foo() {
var people []*Person
likes := make(map[string][]*Person)
for _, p := range people {
for _, l := range p.Likes {
likes[l] = append(likes[l], p) //This line
}
}
fmt.Println(likes)
}

Now for the assembly listing, as it appears on my machine (linux/amd64).
Everything but the critical section is elided, for brevity.

$ go tool compile -S foo.go
"".foo t=1 size=742 args=0x0 locals=0xd0
0x0000 00000 (foo.go:12) TEXT "".foo(SB), $208-0
0x0000 00000 (foo.go:12) MOVQ (TLS), CX
0x0009 00009 (foo.go:12) LEAQ -80(SP), AX
0x000e 00014 (foo.go:12) CMPQ AX, 16(CX)
0x0012 00018 (foo.go:12) JLS 732
0x0018 00024 (foo.go:12) SUBQ $208, SP
0x001f 00031 (foo.go:12) MOVQ BP, 200(SP)
0x0027 00039 (foo.go:12) LEAQ 200(SP), BP
0x002f 00047 (foo.go:12) FUNCDATA $0, 
gclocals·3e27b3aa6b89137cce48b3379a2a6610(SB)
0x002f 00047 (foo.go:12) FUNCDATA $1, 
gclocals·c0d3101dde958787c02a66c7a040e782(SB)
0x002f 00047 (foo.go:14) LEAQ type.map[string][]*"".Person(SB), AX
0x0036 00054 (foo.go:14) MOVQ AX, (SP)
0x003a 00058 (foo.go:14) MOVQ $0, 8(SP)
0x0043 00067 (foo.go:14) MOVQ $0, 16(SP)
0x004c 00076 (foo.go:14) MOVQ $0, 24(SP)
0x0055 00085 (foo.go:14) PCDATA $0, $0
0x0055 00085 (foo.go:14) CALL runtime.makemap(SB)
0x005a 00090 (foo.go:14) MOVQ 32(SP), AX
0x005f 00095 (foo.go:14) MOVQ AX, "".likes+112(SP)
0x0064 00100 (foo.go:15) MOVQ $0, CX
0x0066 00102 (foo.go:13) MOVQ $0, DX
0x0068 00104 (foo.go:15) MOVQ CX, "".autotmp_19+96(SP)
0x006d 00109 (foo.go:15) MOVQ DX, "".autotmp_20+136(SP)
0x0075 00117 (foo.go:15) TESTQ CX, CX
0x0078 00120 (foo.go:15) JGE $0, 493
0x007e 00126 (foo.go:15) MOVQ (DX), BX
0x0081 00129 (foo.go:15) MOVQ BX, "".p+104(SP)
0x0086 00134 (foo.go:16) MOVQ 16(BX), SI
0x008a 00138 (foo.go:16) MOVQ 24(BX), DI
0x008e 00142 (foo.go:16) MOVQ DI, "".autotmp_21+88(SP)
0x0093 00147 (foo.go:15) MOVQ $0, R8
0x0096 00150 (foo.go:16) MOVQ R8, "".autotmp_22+80(SP)
0x009b 00155 (foo.go:16) MOVQ SI, "".autotmp_23+128(SP)
0x00a3 00163 (foo.go:16) CMPQ R8, DI
0x00a6 00166 (foo.go:16) JGE $0, 464
0x00ac 00172 (foo.go:16) MOVQ (SI), R9
0x00af 00175 (foo.go:16) MOVQ 8(SI), R10
0x00b3 00179 (foo.go:17) MOVQ R9, "".autotmp_2+144(SP)
0x00bb 00187 (foo.go:17) MOVQ R10, "".autotmp_2+152(SP)
0x00c3 00195 (foo.go:14) LEAQ type.map[string][]*"".Person(SB), R11
0x00ca 00202 (foo.go:17) MOVQ R11, (SP)
0x00ce 00206 (foo.go:17) MOVQ AX, 8(SP)
0x00d3 00211 (foo.go:17) MOVQ R9, 16(SP)
0x00d8 00216 (foo.go:17) MOVQ R10, 24(SP)
0x00dd 00221 (foo.go:17) PCDATA $0, $1
0x00dd 00221 (foo.go:17) CALL runtime.mapaccess1_faststr(SB)
0x00e2 00226 (foo.go:17) MOVQ 32(SP), AX
0x00e7 00231 (foo.go:17) MOVQ 8(AX), CX
0x00eb 00235 (foo.go:17) MOVQ CX, "".autotmp_24+72(SP)
0x00f0 00240 (foo.go:17) MOVQ 16(AX), DX
0x00f4 00244 (foo.go:17) MOVQ (AX), AX
0x00f7 00247 (foo.go:17) LEAQ 1(CX), BX
0x00fb 00251 (foo.go:17) CMPQ BX, DX
0x00fe 00254 (foo.go:17) JGT $0, 667
0x0104 00260 (foo.go:17) MOVQ AX, "".autotmp_25+120(SP)
0x0109 00265 (foo.go:17) MOVQ BX, "".autotmp_24+72(SP)
0x010e 00270 (foo.go:17) MOVQ DX, "".autotmp_26+64(SP)
0x0113 00275 (foo.go:17) LEAQ (AX)(CX*8), SI
0x0117 00279 (foo.go:17) MOVL runtime.writeBarrier(SB), DI
0x011d 00285 (foo.go:17) TESTB DIB, DIB
0x0120 00288 (foo.go:17) JNE $0, 623
0x0126 00294 (foo.go:17) MOVQ "".p+104(SP), SI
0x012b 00299 (foo.go:17) MOVQ SI, (AX)(CX*8)
0x012f 00303 (foo.go:17) MOVQ BX, "".autotmp_5+184(SP)
0x0137 00311 (foo.go:17) MOVQ DX, "".autotmp_5+192(SP)
0x013f 00319 (foo.go:17) MOVL runtime.writeBarrier(SB), CX
0x0145 00325 (foo.go:17) TESTB CL, CL
0x0147 00327 (foo.go:17) JNE $0, 591
0x014d 00333 (foo.go:17) MOVQ AX, "".autotmp_5+176(SP)
0x0155 00341 (foo.go:14) LEAQ type.map[string][]*"".Person(SB), AX
0x015c 00348 (foo.go:17) MOVQ AX, (SP)
0x0160 00352 (foo.go:17) MOVQ "".likes+112(SP), CX
0x0165 00357 (foo.go:17) MOVQ CX, 8(SP)
0x016a 00362 (foo.go:17) LEAQ "".autotmp_2+144(SP), DX
0x0172 00370 (foo.go:17) MOVQ DX, 16(SP)
0x0177 00375 (foo.go:17) LEAQ "".autotmp_5+176(SP), DX
0x017f 00383 (foo.go:17) MOVQ DX, 24(SP)
0x0184 00388 (foo.go:17) PCDATA $0, $3
0x0184 00388 (foo.go:17) CALL runtime.mapassign1(SB)
0x0189 00393 (foo.go:16) MOVQ "".autotmp_23+128(SP), R9
0x0191 00401 (foo.go:16) LEAQ 16(R9), SI
0x0195 00405 (foo.go:16) MOVQ "".autotmp_22+80(SP), R9
0x019a 00410 (foo.go:16) LEAQ 1(R9), R8
0x019e 00414 (foo.go:14) MOVQ "".likes+112(SP), AX
0x01a3 00419 (foo.go:15) MOVQ "".autotmp_19+96(SP), CX
0x01a8 00424 (foo.go:15) MOVQ "".autotmp_20+136(SP), DX
0x01b0 00432 (foo.go:15) MOVQ "".p+104(SP), BX
0x01b5 00437 (foo.go:16) MOVQ "".autotmp_21+88(SP), DI
0x01ba 00442 (foo.go:16) MOVQ R8, "".autotmp_22+80(SP)
0x01bf 00447 (foo.go:16) MOVQ SI, "".autotmp_23+128(SP)
0x01c7 00455 (foo.go:16) CMPQ R8, DI
0x01ca 00458 (foo.go:16) JLT $0, 172
0x01d0 00464 (foo.go:15) ADDQ $8, DX
0x01d4 00468 (foo.go:15) INCQ CX
0x01d7 00471 (foo.go:15) MOVQ CX, "".autotmp_19+96(SP)
0x01dc 00476 (foo.go:15) MOVQ DX, "".autotmp_20+136(SP)
0x01e4 00484 (foo.go:15) TESTQ CX, CX
0x01e7 00487 (foo.go:15) JLT $0, 126
0x01ed 00493 (foo.go:20) MOVQ $0, "".autotmp_18+160(SP)
0x01f9 00505 (foo.go:20) MOVQ $0, "".autotmp_18+168(SP)
0x0205 00517 (foo.go:14) LEAQ type.map[string][]*"".Person(SB), CX
0x020c 00524 (foo.go:20) MOVQ CX, "".autotmp_18+160(SP)
0x0214 00532 (foo.go:20) MOVQ AX, "".autotmp_18+168(SP)
0x021c 00540 (foo.go:20) LEAQ "".autotmp_18+160(SP), AX
0x0224 00548 (foo.go:20) MOVQ AX, (SP)
0x0228 00552 (foo.go:20) MOVQ $1, 8(SP)
0x0231 00561 (foo.go:20) MOVQ $1, 16(SP)
0x023a 00570 (foo.go:20) PCDATA $0, $4
0x023a 00570 (foo.go:20) CALL fmt.Println(SB)
0x023f 00575 (foo.go:21) MOVQ 200(SP), BP
0x0247 00583 (foo.go:21) ADDQ $208, SP
0x024e 00590 (foo.go:21) RET
0x024f 00591 (foo.go:17) LEAQ "".autotmp_5+176(SP), CX
0x0257 00599 (foo.go:17) MOVQ CX, (SP)
0x025b 00603 (foo.go:17) MOVQ AX, 8(SP)
0x0260 00608 (foo.go:17) PCDATA $0, $3
0x0260 00608 (foo.go:17) CALL runtime.writebarrierptr(SB)
0x0265 00613 (foo.go:15) MOVQ "".p+104(SP), SI
0x026a 00618 (foo.go:14) JMP 341
0x026f 00623 (foo.go:17) MOVQ SI, (SP)
0x0273 00627 (foo.go:17) MOVQ "".p+104(SP), CX
0x0278 00632 (foo.go:17) MOVQ CX, 8(SP)
0x027d 00637 (foo.go:17) PCDATA $0, $2
0x027d 00637 (foo.go:17) CALL runtime.writebarrierptr(SB)
0x0282 00642 (foo.go:17) MOVQ "".autotmp_25+120(SP), AX
0x0287 00647 (foo.go:17) MOVQ "".autotmp_26+64(SP), DX
0x028c 00652 (foo.go:17) MOVQ "".autotmp_24+72(SP), BX
0x0291 00657 (foo.go:15) MOVQ "".p+104(SP), SI
0x0296 00662 (foo.go:17) JMP 303
0x029b 00667 (foo.go:17) LEAQ type.*"".Person(SB), SI
0x02a2 00674 (foo.go:17) MOVQ SI, (SP)
0x02a6 00678 (foo.go:17) MOVQ AX, 8(SP)
0x02ab 00683 (foo.go:17) MOVQ CX, 16(SP)
0x02b0 00688 (foo.go:17) MOVQ DX, 24(SP)
0x02b5 00693 (foo.go:17) MOVQ BX, 32(SP)
0x02ba 00698 (foo.go:17) PCDATA $0, $1
0x02ba 00698 (foo.go:17) CALL runtime.growslice(SB)
0x02bf 00703 (foo.go:17) MOVQ 40(SP), AX
0x02c4 00708 (foo.go:17) MOVQ 48(SP), SI
0x02c9 00713 (foo.go:17) MOVQ 56(SP), DX
0x02ce 00718 (foo.go:17) LEAQ 1(SI), BX
0x02d2 00722 (foo.go:17) MOVQ "".autotmp_24+72(SP), CX
0x02d7 00727 (foo.go:17) JMP 260
0x02dc 00732 (foo.go:17) NOP
0x02dc 00732 (foo.go:12) CALL runtime.morestack_noctxt(SB)
0x02e1 00737 (foo.go:12) JMP 0

In the inner loop, there is a single call to runtime.mapaccess1_faststr 
<https://golang.org/src/runtime/hashmap_fast.go#L192> and a single call to 
runtime.mapassign1 <https://golang.org/src/runtime/hashmap.go#L442>.

On Sunday, November 27, 2016 at 2:36:49 PM UTC+1, stinkin...@gmail.com 
wrote:
>
> The following code is taken from https://blog.golang.org/go-maps-in-action
> .
>
>     type Person struct {        Name  string        Likes []string    }    
> var people []*Person    *likes := make(map[string][]*Person)*    for _, p := 
> range people {        for _, l := range p.Likes {            *likes[l] = 
> append(likes[l], p)    //This line*        }    }
>
>
> Am I being paranoid in thinking the line with two likes[l] is actually doing 
> two lookups ( two hashes, two probes ) and should be eliminated somehow?
>
> Coming from a C++ background ( gophers have mercy :P ), things like this 
> really bothers me.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to