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 <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
Ian Lance Taylor 2024-05-21 21:07:32 -07:00 committed by Gopher Robot
parent 8034488781
commit bb2a5f0556
9 changed files with 45 additions and 52 deletions

View File

@ -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

View File

@ -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, ", "))
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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")

View File

@ -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
}

View File

@ -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,

View File

@ -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)

View File

@ -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.