Derek Parker
c5ba9d2232
cmd/compile: prioritize non-CALL struct member comparisons
...
This patch optimizes reflectdata.geneq to pick apart structs in array
equality and prioritize non-CALL comparisons over those which involve
a runtime function call. This is similar to how arrays of strings
operate currently. Instead of looping over the entire array of structs
once, if there are any comparisons which involve a runtime function
call we instead loop twice. The first loop is all simple, quick
comparisons. If no inequality is found in the first loop the second loop
calls runtime functions for larger memory comparison, which is more
expensive.
For the benchmarks added in this change:
Old:
```
goos: linux
goarch: amd64
pkg: cmd/compile/internal/reflectdata
cpu: AMD Ryzen 9 3950X 16-Core Processor
BenchmarkEqArrayOfStructsEq
BenchmarkEqArrayOfStructsEq-32 797196 1497 ns/op
BenchmarkEqArrayOfStructsEq-32 758332 1581 ns/op
BenchmarkEqArrayOfStructsEq-32 764871 1599 ns/op
BenchmarkEqArrayOfStructsEq-32 760706 1558 ns/op
BenchmarkEqArrayOfStructsEq-32 763112 1476 ns/op
BenchmarkEqArrayOfStructsEq-32 747696 1547 ns/op
BenchmarkEqArrayOfStructsEq-32 756526 1562 ns/op
BenchmarkEqArrayOfStructsEq-32 768829 1486 ns/op
BenchmarkEqArrayOfStructsEq-32 764248 1477 ns/op
BenchmarkEqArrayOfStructsEq-32 752767 1545 ns/op
BenchmarkEqArrayOfStructsNotEq
BenchmarkEqArrayOfStructsNotEq-32 757194 1542 ns/op
BenchmarkEqArrayOfStructsNotEq-32 748942 1552 ns/op
BenchmarkEqArrayOfStructsNotEq-32 766687 1554 ns/op
BenchmarkEqArrayOfStructsNotEq-32 732069 1541 ns/op
BenchmarkEqArrayOfStructsNotEq-32 759163 1576 ns/op
BenchmarkEqArrayOfStructsNotEq-32 796402 1629 ns/op
BenchmarkEqArrayOfStructsNotEq-32 726610 1570 ns/op
BenchmarkEqArrayOfStructsNotEq-32 735770 1584 ns/op
BenchmarkEqArrayOfStructsNotEq-32 745255 1610 ns/op
BenchmarkEqArrayOfStructsNotEq-32 743872 1591 ns/op
PASS
ok cmd/compile/internal/reflectdata 35.446s
```
New:
```
goos: linux
goarch: amd64
pkg: cmd/compile/internal/reflectdata
cpu: AMD Ryzen 9 3950X 16-Core Processor
BenchmarkEqArrayOfStructsEq
BenchmarkEqArrayOfStructsEq-32 618379 1827 ns/op
BenchmarkEqArrayOfStructsEq-32 619368 1922 ns/op
BenchmarkEqArrayOfStructsEq-32 616023 1910 ns/op
BenchmarkEqArrayOfStructsEq-32 617575 1905 ns/op
BenchmarkEqArrayOfStructsEq-32 610399 1889 ns/op
BenchmarkEqArrayOfStructsEq-32 615378 1823 ns/op
BenchmarkEqArrayOfStructsEq-32 613732 1883 ns/op
BenchmarkEqArrayOfStructsEq-32 613924 1894 ns/op
BenchmarkEqArrayOfStructsEq-32 657799 1876 ns/op
BenchmarkEqArrayOfStructsEq-32 665580 1873 ns/op
BenchmarkEqArrayOfStructsNotEq
BenchmarkEqArrayOfStructsNotEq-32 1834915 627.4 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1806370 660.5 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1828075 625.5 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1819741 641.6 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1813128 632.3 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1865250 643.7 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1828617 632.8 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1862748 633.6 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1825432 638.7 ns/op
BenchmarkEqArrayOfStructsNotEq-32 1804382 628.8 ns/op
PASS
ok cmd/compile/internal/reflectdata 36.571s
```
Benchstat comparison:
```
name old time/op new time/op delta
EqArrayOfStructsEq-32 1.53µs ± 4% 1.88µs ± 3% +22.66% (p=0.000 n=10+10)
EqArrayOfStructsNotEq-32 1.57µs ± 3% 0.64µs ± 4% -59.59% (p=0.000 n=10+10)
```
So, the equal case is a bit slower (unrolling the loop helps with that),
but the non-equal case is now much faster.
Change-Id: I05d776456c79c48a3d6d74b18c45246e58ffbea6
GitHub-Last-Rev: f57ee07d05
GitHub-Pull-Request: golang/go#59409
Reviewed-on: https://go-review.googlesource.com/c/go/+/481895
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2023-05-24 21:55:14 +00:00
Keith Randall
8c8045fd38
cmd/compile: fix ordering problems in struct equality
...
Make sure that if a field comparison might panic, we evaluate
(and short circuit if not equal) all previous fields, and don't
evaluate any subsequent fields.
Add a bunch more tests to the equality+panic checker.
Update #8606
Change-Id: I6a159bbc8da5b2b7ee835c0cd1fc565575b58c46
Reviewed-on: https://go-review.googlesource.com/c/go/+/237919
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-06-15 18:03:08 +00:00
Keith Randall
f72d7cfc8f
cmd/compile: add interface equality tests
...
Add interfaces which differ in type. Those used so far only
differ in value, not type.
These additional tests are needed to generate a failure
before CL 236278 went in.
Update #8606
Change-Id: Icdb7647b1973c2fff7e5afe2bd8b8c1b384f583e
Reviewed-on: https://go-review.googlesource.com/c/go/+/236418
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-06-04 06:21:55 +00:00
Keith Randall
9984ef824c
cmd/compile: test that equality is evaluated in order
...
Make sure that we compare fields of structs and elements of arrays in order,
with proper short-circuiting.
Update #8606
Change-Id: I0a66ad92ea0af7bcc56dfdb275dec2b8d7e8b4fe
Reviewed-on: https://go-review.googlesource.com/c/go/+/236147
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-06-03 19:07:55 +00:00