Skip to content

Commit ec091b6

Browse files
huguesbjosharian
authored andcommitted
runtime: add mapassign_fast*
Add benchmarks for map assignment with int32/int64/string key Benchmark results on darwin/amd64 name old time/op new time/op delta MapAssignInt32_255-8 24.7ns ± 3% 17.4ns ± 2% -29.75% (p=0.000 n=10+10) MapAssignInt32_64k-8 45.5ns ± 4% 37.6ns ± 4% -17.18% (p=0.000 n=10+10) MapAssignInt64_255-8 26.0ns ± 3% 17.9ns ± 4% -31.03% (p=0.000 n=10+10) MapAssignInt64_64k-8 46.9ns ± 5% 38.7ns ± 2% -17.53% (p=0.000 n=9+10) MapAssignStr_255-8 47.8ns ± 3% 24.8ns ± 4% -48.01% (p=0.000 n=10+10) MapAssignStr_64k-8 83.0ns ± 3% 51.9ns ± 3% -37.45% (p=0.000 n=10+9) name old time/op new time/op delta BinaryTree17-8 3.11s ±19% 2.78s ± 3% ~ (p=0.095 n=5+5) Fannkuch11-8 3.26s ± 1% 3.21s ± 2% ~ (p=0.056 n=5+5) FmtFprintfEmpty-8 50.3ns ± 1% 50.8ns ± 2% ~ (p=0.246 n=5+5) FmtFprintfString-8 82.7ns ± 4% 80.1ns ± 5% ~ (p=0.238 n=5+5) FmtFprintfInt-8 82.6ns ± 2% 81.9ns ± 3% ~ (p=0.508 n=5+5) FmtFprintfIntInt-8 124ns ± 4% 121ns ± 3% ~ (p=0.111 n=5+5) FmtFprintfPrefixedInt-8 158ns ± 6% 160ns ± 2% ~ (p=0.341 n=5+5) FmtFprintfFloat-8 249ns ± 2% 245ns ± 2% ~ (p=0.095 n=5+5) FmtManyArgs-8 513ns ± 2% 519ns ± 3% ~ (p=0.151 n=5+5) GobDecode-8 7.48ms ±12% 7.11ms ± 2% ~ (p=0.222 n=5+5) GobEncode-8 6.25ms ± 1% 6.03ms ± 2% -3.56% (p=0.008 n=5+5) Gzip-8 252ms ± 4% 252ms ± 4% ~ (p=1.000 n=5+5) Gunzip-8 38.4ms ± 3% 38.6ms ± 2% ~ (p=0.690 n=5+5) HTTPClientServer-8 76.9µs ±41% 66.4µs ± 6% ~ (p=0.310 n=5+5) JSONEncode-8 16.5ms ± 3% 16.7ms ± 3% ~ (p=0.421 n=5+5) JSONDecode-8 54.6ms ± 1% 54.3ms ± 2% ~ (p=0.548 n=5+5) Mandelbrot200-8 4.45ms ± 3% 4.47ms ± 1% ~ (p=0.841 n=5+5) GoParse-8 3.43ms ± 1% 3.32ms ± 2% -3.28% (p=0.008 n=5+5) RegexpMatchEasy0_32-8 88.2ns ± 3% 89.4ns ± 2% ~ (p=0.333 n=5+5) RegexpMatchEasy0_1K-8 205ns ± 1% 206ns ± 1% ~ (p=0.905 n=5+5) RegexpMatchEasy1_32-8 85.1ns ± 1% 85.5ns ± 5% ~ (p=0.690 n=5+5) RegexpMatchEasy1_1K-8 365ns ± 1% 371ns ± 9% ~ (p=1.000 n=5+5) RegexpMatchMedium_32-8 129ns ± 2% 128ns ± 3% ~ (p=0.730 n=5+5) RegexpMatchMedium_1K-8 39.8µs ± 0% 39.7µs ± 4% ~ (p=0.730 n=4+5) RegexpMatchHard_32-8 1.99µs ± 3% 2.05µs ±16% ~ (p=0.794 n=5+5) RegexpMatchHard_1K-8 59.3µs ± 1% 60.3µs ± 7% ~ (p=1.000 n=5+5) Revcomp-8 1.36s ±63% 0.52s ± 5% ~ (p=0.095 n=5+5) Template-8 62.6ms ±14% 60.5ms ± 5% ~ (p=0.690 n=5+5) TimeParse-8 330ns ± 2% 324ns ± 2% ~ (p=0.087 n=5+5) TimeFormat-8 350ns ± 3% 340ns ± 1% -2.86% (p=0.008 n=5+5) name old speed new speed delta GobDecode-8 103MB/s ±11% 108MB/s ± 2% ~ (p=0.222 n=5+5) GobEncode-8 123MB/s ± 1% 127MB/s ± 2% +3.71% (p=0.008 n=5+5) Gzip-8 77.1MB/s ± 4% 76.9MB/s ± 3% ~ (p=1.000 n=5+5) Gunzip-8 505MB/s ± 3% 503MB/s ± 2% ~ (p=0.690 n=5+5) JSONEncode-8 118MB/s ± 3% 116MB/s ± 3% ~ (p=0.421 n=5+5) JSONDecode-8 35.5MB/s ± 1% 35.8MB/s ± 2% ~ (p=0.397 n=5+5) GoParse-8 16.9MB/s ± 1% 17.4MB/s ± 2% +3.45% (p=0.008 n=5+5) RegexpMatchEasy0_32-8 363MB/s ± 3% 358MB/s ± 2% ~ (p=0.421 n=5+5) RegexpMatchEasy0_1K-8 4.98GB/s ± 1% 4.97GB/s ± 1% ~ (p=0.548 n=5+5) RegexpMatchEasy1_32-8 376MB/s ± 1% 375MB/s ± 5% ~ (p=0.690 n=5+5) RegexpMatchEasy1_1K-8 2.80GB/s ± 1% 2.76GB/s ± 9% ~ (p=0.841 n=5+5) RegexpMatchMedium_32-8 7.73MB/s ± 1% 7.76MB/s ± 3% ~ (p=0.730 n=5+5) RegexpMatchMedium_1K-8 25.8MB/s ± 0% 25.8MB/s ± 4% ~ (p=0.651 n=4+5) RegexpMatchHard_32-8 16.1MB/s ± 3% 15.7MB/s ±14% ~ (p=0.794 n=5+5) RegexpMatchHard_1K-8 17.3MB/s ± 1% 17.0MB/s ± 7% ~ (p=0.984 n=5+5) Revcomp-8 273MB/s ±83% 488MB/s ± 5% ~ (p=0.095 n=5+5) Template-8 31.1MB/s ±13% 32.1MB/s ± 5% ~ (p=0.690 n=5+5) Updates #19495 Change-Id: I116e9a2a4594769318b22d736464de8a98499909 Reviewed-on: https://go-review.googlesource.com/38091 Reviewed-by: Josh Bleecher Snyder <[email protected]> Reviewed-by: Keith Randall <[email protected]> Run-TryBot: Josh Bleecher Snyder <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 53937aa commit ec091b6

File tree

7 files changed

+366
-25
lines changed

7 files changed

+366
-25
lines changed

src/cmd/compile/internal/gc/builtin.go

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ var runtimeDecls = [...]struct {
8383
{"mapaccess2_faststr", funcTag, 64},
8484
{"mapaccess2_fat", funcTag, 65},
8585
{"mapassign", funcTag, 60},
86+
{"mapassign_fast32", funcTag, 61},
87+
{"mapassign_fast64", funcTag, 61},
88+
{"mapassign_faststr", funcTag, 61},
8689
{"mapiterinit", funcTag, 66},
8790
{"mapdelete", funcTag, 66},
8891
{"mapiternext", funcTag, 67},

src/cmd/compile/internal/gc/builtin/runtime.go

+3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ func mapaccess2_fast64(mapType *byte, hmap map[any]any, key any) (val *any, pres
103103
func mapaccess2_faststr(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
104104
func mapaccess2_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any, pres bool)
105105
func mapassign(mapType *byte, hmap map[any]any, key *any) (val *any)
106+
func mapassign_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
107+
func mapassign_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
108+
func mapassign_faststr(mapType *byte, hmap map[any]any, key any) (val *any)
106109
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
107110
func mapdelete(mapType *byte, hmap map[any]any, key *any)
108111
func mapiternext(hiter *any)

src/cmd/compile/internal/gc/order.go

+12-5
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,20 @@ func orderaddrtemp(n *Node, order *Order) *Node {
206206
return ordercopyexpr(n, n.Type, order, 0)
207207
}
208208

209-
// ordermapkeytemp prepares n.Right to be a key in a map lookup.
209+
// ordermapkeytemp prepares n.Right to be a key in a map runtime call.
210210
func ordermapkeytemp(n *Node, order *Order) {
211211
// Most map calls need to take the address of the key.
212-
// Exception: mapaccessN_fast* calls. See golang.org/issue/19015.
213-
p, _ := mapaccessfast(n.Left.Type)
214-
fastaccess := p != "" && n.Etype == 0 // Etype == 0 iff n is an rvalue
215-
if fastaccess {
212+
// Exception: map(accessN|assign)_fast* calls. See golang.org/issue/19015.
213+
var p string
214+
switch n.Etype {
215+
case 0: // n is an rvalue
216+
p, _ = mapaccessfast(n.Left.Type)
217+
case 1: // n is an lvalue
218+
p = mapassignfast(n.Left.Type)
219+
default:
220+
Fatalf("unexpected node type: %+v", n)
221+
}
222+
if p != "" {
216223
return
217224
}
218225
n.Right = orderaddrtemp(n.Right, order)

src/cmd/compile/internal/gc/walk.go

+26-4
Original file line numberDiff line numberDiff line change
@@ -1184,9 +1184,14 @@ opswitch:
11841184
t := map_.Type
11851185
if n.Etype == 1 {
11861186
// This m[k] expression is on the left-hand side of an assignment.
1187-
// orderexpr made sure key is addressable.
1188-
key = nod(OADDR, key, nil)
1189-
n = mkcall1(mapfn("mapassign", t), nil, init, typename(t), map_, key)
1187+
p := mapassignfast(t)
1188+
if p == "" {
1189+
// standard version takes key by reference.
1190+
// orderexpr made sure key is addressable.
1191+
key = nod(OADDR, key, nil)
1192+
p = "mapassign"
1193+
}
1194+
n = mkcall1(mapfn(p, t), nil, init, typename(t), map_, key)
11901195
} else {
11911196
// m[k] is not the target of an assignment.
11921197
p, _ := mapaccessfast(t)
@@ -2628,7 +2633,7 @@ func mapfndel(name string, t *Type) *Node {
26282633
return fn
26292634
}
26302635

2631-
// mapaccessfast returns the names of the fast map access runtime routines for t.
2636+
// mapaccessfast returns the name of the fast map access runtime routine for t.
26322637
func mapaccessfast(t *Type) (access1, access2 string) {
26332638
// Check ../../runtime/hashmap.go:maxValueSize before changing.
26342639
if t.Val().Width > 128 {
@@ -2645,6 +2650,23 @@ func mapaccessfast(t *Type) (access1, access2 string) {
26452650
return "", ""
26462651
}
26472652

2653+
// mapassignfast returns the name of the fast map assign runtime routine for t.
2654+
func mapassignfast(t *Type) (assign string) {
2655+
// Check ../../runtime/hashmap.go:maxValueSize before changing.
2656+
if t.Val().Width > 128 {
2657+
return ""
2658+
}
2659+
switch algtype(t.Key()) {
2660+
case AMEM32:
2661+
return "mapassign_fast32"
2662+
case AMEM64:
2663+
return "mapassign_fast64"
2664+
case ASTRING:
2665+
return "mapassign_faststr"
2666+
}
2667+
return ""
2668+
}
2669+
26482670
func writebarrierfn(name string, l *Type, r *Type) *Node {
26492671
fn := syslook(name)
26502672
fn = substArgTypes(fn, l, r)

0 commit comments

Comments
 (0)