From bb2a5f0556fd6bb4dbbce5eef2d6317d20796ade Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 21 May 2024 21:07:32 -0700 Subject: [PATCH] cmd: change from sort functions to slices functions Doing this because the slices functions are slightly faster and slightly easier to use. It also removes one dependency layer. We did this outside of bootstrap tools in CL 587655. Now that the bootstrap compiler is 1.22, we can do this in more code. Change-Id: I9ed2dd473758cacd14f76a0639368523ccdff72f Reviewed-on: https://go-review.googlesource.com/c/go/+/626038 Auto-Submit: Ian Lance Taylor Reviewed-by: Ian Lance Taylor LUCI-TryBot-Result: Go LUCI Reviewed-by: Damien Neil --- src/cmd/api/api_test.go | 4 +-- src/cmd/api/main_test.go | 18 ++++++------- .../compile/internal/reflectdata/reflect.go | 2 +- src/cmd/compile/internal/typecheck/subr.go | 2 +- src/cmd/compile/internal/types/size.go | 19 +++++++------- src/cmd/compile/internal/types/sort.go | 16 ------------ src/cmd/compile/internal/types/sym.go | 25 +++++++++++-------- src/cmd/compile/internal/types/sym_test.go | 6 ++--- src/cmd/compile/internal/types/type.go | 5 ++++ 9 files changed, 45 insertions(+), 52 deletions(-) delete mode 100644 src/cmd/compile/internal/types/sort.go diff --git a/src/cmd/api/api_test.go b/src/cmd/api/api_test.go index ba358d364d..7848233333 100644 --- a/src/cmd/api/api_test.go +++ b/src/cmd/api/api_test.go @@ -11,7 +11,7 @@ import ( "internal/testenv" "os" "path/filepath" - "sort" + "slices" "strings" "sync" "testing" @@ -77,7 +77,7 @@ func TestGolden(t *testing.T) { t.Fatalf("opening golden.txt for package %q: %v", fi.Name(), err) } wanted := strings.Split(string(bs), "\n") - sort.Strings(wanted) + slices.Sort(wanted) for _, feature := range wanted { if feature == "" { continue diff --git a/src/cmd/api/main_test.go b/src/cmd/api/main_test.go index 10dbabb9b8..a0820c2274 100644 --- a/src/cmd/api/main_test.go +++ b/src/cmd/api/main_test.go @@ -25,7 +25,7 @@ import ( "path/filepath" "regexp" "runtime" - "sort" + "slices" "strconv" "strings" "sync" @@ -232,8 +232,8 @@ func compareAPI(w io.Writer, features, required, exception []string) (ok bool) { featureSet := set(features) exceptionSet := set(exception) - sort.Strings(features) - sort.Strings(required) + slices.Sort(features) + slices.Sort(required) take := func(sl *[]string) string { s := (*sl)[0] @@ -378,7 +378,7 @@ func (w *Walker) Features() (fs []string) { for f := range w.features { fs = append(fs, f) } - sort.Strings(fs) + slices.Sort(fs) return } @@ -431,7 +431,7 @@ func tagKey(dir string, context *build.Context, tags []string) string { // an indirect imported package. See https://github.com/golang/go/issues/21181 // for more detail. tags = append(tags, context.GOOS, context.GOARCH) - sort.Strings(tags) + slices.Sort(tags) for _, tag := range tags { if ctags[tag] { @@ -535,7 +535,7 @@ func (w *Walker) loadImports() { } } - sort.Strings(stdPackages) + slices.Sort(stdPackages) imports = listImports{ stdPackages: stdPackages, importMap: importMap, @@ -717,7 +717,7 @@ func sortedMethodNames(typ *types.Interface) []string { for i := range list { list[i] = typ.Method(i).Name() } - sort.Strings(list) + slices.Sort(list) return list } @@ -747,7 +747,7 @@ func (w *Walker) sortedEmbeddeds(typ *types.Interface) []string { list = append(list, buf.String()) } } - sort.Strings(list) + slices.Sort(list) return list } @@ -1083,7 +1083,7 @@ func (w *Walker) emitIfaceType(name string, typ *types.Interface) { return } - sort.Strings(methodNames) + slices.Sort(methodNames) w.emitf("type %s interface { %s }", name, strings.Join(methodNames, ", ")) } diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index de7e4755d3..c26ac3d74c 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -145,7 +145,7 @@ func imethods(t *types.Type) []*typeSig { } if n := len(methods); n > 0 { last := methods[n-1] - if !last.name.Less(f.Sym) { + if types.CompareSyms(last.name, f.Sym) >= 0 { base.Fatalf("sigcmp vs sortinter %v %v", last.name, f.Sym) } } diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go index af7ab38638..3b22d260bf 100644 --- a/src/cmd/compile/internal/typecheck/subr.go +++ b/src/cmd/compile/internal/typecheck/subr.go @@ -144,7 +144,7 @@ func CalcMethods(t *types.Type) { } ms = append(ms, t.Methods()...) - slices.SortFunc(ms, types.MethodsByNameCmp) + slices.SortFunc(ms, types.CompareFields) t.SetAllMethods(ms) } diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go index 308245d9b7..48729884df 100644 --- a/src/cmd/compile/internal/types/size.go +++ b/src/cmd/compile/internal/types/size.go @@ -7,7 +7,6 @@ package types import ( "math" "slices" - "sort" "cmd/compile/internal/base" "cmd/internal/src" @@ -94,21 +93,21 @@ func expandiface(t *Type) { { methods := t.Methods() - sort.SliceStable(methods, func(i, j int) bool { - mi, mj := methods[i], methods[j] - + slices.SortStableFunc(methods, func(a, b *Field) int { // Sort embedded types by type name (if any). - if mi.Sym == nil && mj.Sym == nil { - return mi.Type.Sym().Less(mj.Type.Sym()) + if a.Sym == nil && b.Sym == nil { + return CompareSyms(a.Type.Sym(), b.Type.Sym()) } // Sort methods before embedded types. - if mi.Sym == nil || mj.Sym == nil { - return mi.Sym != nil + if a.Sym == nil { + return -1 + } else if b.Sym == nil { + return +1 } // Sort methods by symbol name. - return mi.Sym.Less(mj.Sym) + return CompareSyms(a.Sym, b.Sym) }) } @@ -147,7 +146,7 @@ func expandiface(t *Type) { m.Pos = src.NoXPos } - slices.SortFunc(methods, MethodsByNameCmp) + slices.SortFunc(methods, CompareFields) if int64(len(methods)) >= MaxWidth/int64(PtrSize) { base.ErrorfAt(typePos(t), 0, "interface too large") diff --git a/src/cmd/compile/internal/types/sort.go b/src/cmd/compile/internal/types/sort.go deleted file mode 100644 index 83b1237634..0000000000 --- a/src/cmd/compile/internal/types/sort.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -// MethodsByNameCmp sorts methods by name. -func MethodsByNameCmp(x, y *Field) int { - if x.Sym.Less(y.Sym) { - return -1 - } - if y.Sym.Less(x.Sym) { - return +1 - } - return 0 -} diff --git a/src/cmd/compile/internal/types/sym.go b/src/cmd/compile/internal/types/sym.go index 67fa6bb1d0..97175d745c 100644 --- a/src/cmd/compile/internal/types/sym.go +++ b/src/cmd/compile/internal/types/sym.go @@ -7,6 +7,7 @@ package types import ( "cmd/compile/internal/base" "cmd/internal/obj" + "strings" "unicode" "unicode/utf8" ) @@ -92,39 +93,43 @@ func (sym *Sym) LinksymABI(abi obj.ABI) *obj.LSym { return base.PkgLinksym(sym.Pkg.Prefix, sym.Name, abi) } -// Less reports whether symbol a is ordered before symbol b. +// CompareSyms return the ordering of a and b, as for [cmp.Compare]. // // Symbols are ordered exported before non-exported, then by name, and // finally (for non-exported symbols) by package path. -func (a *Sym) Less(b *Sym) bool { +func CompareSyms(a, b *Sym) int { if a == b { - return false + return 0 } // Nil before non-nil. if a == nil { - return true + return -1 } if b == nil { - return false + return +1 } // Exported symbols before non-exported. ea := IsExported(a.Name) eb := IsExported(b.Name) if ea != eb { - return ea + if ea { + return -1 + } else { + return +1 + } } // Order by name and then (for non-exported names) by package // height and path. - if a.Name != b.Name { - return a.Name < b.Name + if r := strings.Compare(a.Name, b.Name); r != 0 { + return r } if !ea { - return a.Pkg.Path < b.Pkg.Path + return strings.Compare(a.Pkg.Path, b.Pkg.Path) } - return false + return 0 } // IsExported reports whether name is an exported Go symbol (that is, diff --git a/src/cmd/compile/internal/types/sym_test.go b/src/cmd/compile/internal/types/sym_test.go index 94efd42aa4..cdb17c36f5 100644 --- a/src/cmd/compile/internal/types/sym_test.go +++ b/src/cmd/compile/internal/types/sym_test.go @@ -7,11 +7,11 @@ package types_test import ( "cmd/compile/internal/types" "reflect" - "sort" + "slices" "testing" ) -func TestSymLess(t *testing.T) { +func TestSymCompare(t *testing.T) { var ( local = types.NewPkg("", "") abc = types.NewPkg("abc", "") @@ -50,7 +50,7 @@ func TestSymLess(t *testing.T) { if reflect.DeepEqual(data, want) { t.Fatal("data must be shuffled") } - sort.Slice(data, func(i, j int) bool { return data[i].Less(data[j]) }) + slices.SortFunc(data, types.CompareSyms) if !reflect.DeepEqual(data, want) { t.Logf("want: %#v", want) t.Logf("data: %#v", data) diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index 9d3dde8c13..79c890d46c 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -458,6 +458,11 @@ func (f *Field) IsMethod() bool { return f.Type.kind == TFUNC && f.Type.Recv() != nil } +// CompareFields compares two Field values by name. +func CompareFields(a, b *Field) int { + return CompareSyms(a.Sym, b.Sym) +} + // fields is a pointer to a slice of *Field. // This saves space in Types that do not have fields or methods // compared to a simple slice of *Field. -- 2.48.1