./cmd/vet/vet_test.go: if _, suffix, ok := strings.Cut(text, " "); ok {
./cmd/go/scriptreadme_test.go: _, lang, ok := strings.Cut(doc.String(), "# Script Language\n\n")
./cmd/go/scriptreadme_test.go: lang, _, ok = strings.Cut(lang, "\n\nvar ")
./cmd/go/internal/test/test.go: op, name, found := strings.Cut(s, " ")
./cmd/go/internal/vcweb/script.go: mPath, version, ok := strings.Cut(args[1], "@")
./cmd/go/internal/modfetch/fetch.go: _, vers, _ = strings.Cut(vers, "-")
./cmd/go/internal/modfetch/fetch.go: goos, goarch, _ := strings.Cut(vers[i+1:], "-")
./cmd/go/internal/modfetch/codehost/vcs.go: before, after, found := strings.Cut(line, ":")
./cmd/go/internal/modfetch/toolchain.go: _, v, ok := strings.Cut(v, "-")
./cmd/go/internal/modload/list.go: if path, vers, found := strings.Cut(arg, "@"); found {
./cmd/go/internal/modload/list.go: if path, vers, found := strings.Cut(arg, "@"); found {
./cmd/go/internal/modload/build.go: if path, vers, found := strings.Cut(path, "@"); found {
./cmd/go/internal/modload/search.go: elem, rest, found := strings.Cut(p, string(filepath.Separator))
./cmd/go/internal/modload/init.go: line, _, _ := strings.Cut(string(buf[:n]), "\n")
./cmd/go/internal/envcmd/env.go: key, val, found := strings.Cut(arg, "=")
./cmd/go/internal/modindex/build.go: line, argstr, ok := strings.Cut(strings.TrimSpace(line[4:]), ":")
./cmd/go/internal/modindex/build.go: name, _, _ = strings.Cut(name, ".")
./cmd/go/internal/modindex/build_read.go: path, _, ok = strings.Cut(args[1:], "`")
./cmd/go/internal/script/engine.go: prefix, suffix, ok := strings.Cut(cond.tag, ":")
./cmd/go/internal/script/engine.go: if prefix, suffix, ok := strings.Cut(tag, ":"); ok {
./cmd/go/internal/script/state.go: if k, v, ok := strings.Cut(kv, "="); ok {
./cmd/go/internal/modcmd/edit.go: before, after, found := strings.Cut(arg, "@")
./cmd/go/internal/modcmd/edit.go: before, after, found := strings.Cut(arg, "@")
./cmd/go/internal/modcmd/edit.go: before, after, found := strings.Cut(s, ",")
./cmd/go/internal/modcmd/edit.go: before, after, found := strings.Cut(arg, "=")
./cmd/go/internal/load/godebug.go: k, v, ok := strings.Cut(strings.TrimSpace(text[i:]), "=")
./cmd/go/internal/vcs/vcs.go: pattern, list, found := strings.Cut(item, ":")
./cmd/go/internal/vcs/vcs.go: if scheme, path, ok := strings.Cut(repo, "://"); ok {
./cmd/go/internal/work/gccgo.go: before, after, _ := strings.Cut(args, "=")
./cmd/go/internal/gover/gomod.go: s, _, _ = strings.Cut(s, "//") // strip comments
./cmd/go/internal/gover/mod_test.go: path, vers, _ := strings.Cut(f, " ")
./cmd/go/internal/modget/query.go: pattern, rawVers, found := strings.Cut(raw, "@")
./cmd/go/internal/cmdflag/flag.go: name, value, hasValue := strings.Cut(arg[1:], "=")
./cmd/go/internal/workcmd/edit.go: before, after, found := strings.Cut(arg, "@")
./cmd/go/internal/workcmd/edit.go: before, after, found := strings.Cut(arg, "=")
./cmd/go/internal/toolchain/select.go: min, suffix, plus := strings.Cut(gotoolchain, "+") // go1.2.3+auto
./cmd/go/internal/toolchain/select.go: name, val, hasEq := strings.Cut(a, "=")
./cmd/go/internal/toolchain/select.go: name, _, _ := strings.Cut(a, "=")
./cmd/go/internal/toolchain/select.go: path, version, _ := strings.Cut(pkgArg, "@")
./cmd/go/main.go: _, dir, _ = strings.Cut(a, "=")
./cmd/distpack/pack.go: version, rest, _ := strings.Cut(string(data), "\n")
./cmd/internal/testdir/testdir_test.go: goos, goarch, ok := strings.Cut(*target, "/")
./cmd/internal/testdir/testdir_test.go: line, actionSrc, _ = strings.Cut(actionSrc, "\n")
./cmd/internal/testdir/testdir_test.go: header, _, ok := strings.Cut(src, "\npackage")
./cmd/internal/testdir/testdir_test.go: if _, suffix, ok := strings.Cut(text, " "); ok {
./cmd/internal/testdir/testdir_test.go: lines[i], _, _ = strings.Cut(lines[i], " // ERROR ")
./cmd/internal/testdir/testdir_test.go: errFile, rest, ok := strings.Cut(errStr, ":")
./cmd/internal/testdir/testdir_test.go: lineStr, msg, ok := strings.Cut(rest, ":")
./cmd/compile/internal/base/flag.go: verb, args, found := strings.Cut(line, " ")
./cmd/compile/internal/base/flag.go: before, after, hasEq := strings.Cut(args, "=")
./cmd/link/internal/ld/ld.go: verb, args, found := strings.Cut(line, " ")
./cmd/link/internal/ld/ld.go: before, after, exist := strings.Cut(args, "=")
./cmd/link/internal/ld/go.go: line, data, _ = strings.Cut(data, "\n")
./cmd/link/internal/ld/go.go: if before, after, found := strings.Cut(remote, "#"); found {
./cmd/cgo/internal/testcshared/cshared_test.go: switch prefix, _, _ := strings.Cut(name, "-"); prefix {
./cmd/fix/typecheck.go: if _, elem, ok := strings.Cut(t, "]"); ok {
./cmd/fix/typecheck.go: if _, et, ok := strings.Cut(t, "]"); ok {
./cmd/fix/typecheck.go: if kt, vt, ok := strings.Cut(t[len("map["):], "]"); ok {
./cmd/fix/typecheck.go: _, value, _ = strings.Cut(t, "]")
./cmd/fix/typecheck.go: if k, v, ok := strings.Cut(t[len("map["):], "]"); ok {
./cmd/api/main_test.go: feature, approval, ok := strings.Cut(line, "#")
./cmd/doc/dirs.go: path, dir, _ := strings.Cut(line, "\t")
./cmd/vendor/golang.org/x/tools/cmd/bisect/main.go: if _, v, _ := strings.Cut(e, "="); strings.Contains(v, "PATTERN") {
./cmd/vendor/golang.org/x/tools/cmd/bisect/main.go: k, v, _ := strings.Cut(x, "=")
./cmd/vendor/golang.org/x/tools/cmd/bisect/main.go: line, all, _ = strings.Cut(all, "\n")
./cmd/vendor/golang.org/x/tools/go/analysis/passes/directive/directive.go: line, text, _ = strings.Cut(text, "\n")
./cmd/vendor/golang.org/x/tools/go/analysis/passes/directive/directive.go: _, line, ok = strings.Cut(line, "*/")
./cmd/vendor/golang.org/x/tools/internal/versions/versions.go: v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix.
./cmd/vendor/golang.org/x/tools/internal/stdlib/stdlib.go: typename, name, _ = strings.Cut(sym.Name, ".")
./cmd/vendor/golang.org/x/tools/internal/stdlib/stdlib.go: recv, name, _ = strings.Cut(sym.Name, ".")
./cmd/vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go: _, pcstr, ok := strings.Cut(line, " pc=") // e.g. pc=0x%x
./cmd/vendor/golang.org/x/telemetry/internal/config/config.go: prefix, _, found := strings.Cut(c.Name, ":")
./cmd/vendor/golang.org/x/telemetry/internal/config/config.go: prefix, rest, hasBuckets := strings.Cut(counter, "{")
./cmd/vendor/golang.org/x/telemetry/internal/counter/parse.go: k, v, ok := strings.Cut(line, ": ")
./cmd/vendor/golang.org/x/telemetry/internal/upload/reports.go: before, _, _ := strings.Cut(k, "\n")
./cmd/vendor/golang.org/x/build/relnote/relnote.go: dir, rest, _ := strings.Cut(filename, "/")
./cmd/vendor/golang.org/x/build/relnote/relnote.go: dir, rest, _ = strings.Cut(rest, "/")
./crypto/ecdsa/ecdsa_test.go: curve, hash, _ := strings.Cut(line, ",")
./crypto/x509/pem_decrypt.go: mode, hexIV, ok := strings.Cut(dek, ",")
./crypto/x509/verify_test.go: before, _, ok := strings.Cut(string(out), ".")
./crypto/tls/handshake_test.go: _, after, ok := strings.Cut(line, " ")
./crypto/tls/handshake_test.go: before, _, ok := strings.Cut(line, "|")
./strconv/fp_test.go: if mant, exp, ok := strings.Cut(s, "p"); ok {
./strconv/fp_test.go: if mant, exp, ok := strings.Cut(s, "p"); ok {
./strings/example_test.go: before, after, found := strings.Cut(s, sep)
./net/mail/message.go: k, v, ok := strings.Cut(kv, ":")
./net/platform_test.go: net, _, _ := strings.Cut(network, ":")
./net/platform_test.go: switch net, _, _ := strings.Cut(network, ":"); net {
./net/platform_test.go: switch net, _, _ := strings.Cut(network, ":"); net {
./net/url/url.go: u, frag, _ := strings.Cut(rawURL, "#")
./net/url/url.go: rest, url.RawQuery, _ = strings.Cut(rest, "?")
./net/url/url.go: if segment, _, _ := strings.Cut(rest, "/"); strings.Contains(segment, ":") {
./net/url/url.go: username, password, _ := strings.Cut(userinfo, ":")
./net/url/url.go: if segment, _, _ := strings.Cut(path, "/"); strings.Contains(segment, ":") {
./net/url/url.go: key, query, _ = strings.Cut(query, "&")
./net/url/url.go: key, value, _ := strings.Cut(key, "=")
./net/url/url.go: elem, remaining, found = strings.Cut(remaining, "/")
./net/main_posix_test.go: net, _, _ := strings.Cut(network, ":")
./net/http/transport.go: _, text, ok := strings.Cut(resp.Status, " ")
./net/http/response.go: proto, status, ok := strings.Cut(line, " ")
./net/http/response.go: statusCode, _, _ := strings.Cut(resp.Status, " ")
./net/http/request.go: username, password, ok = strings.Cut(cs, ":")
./net/http/request.go: method, rest, ok1 := strings.Cut(line, " ")
./net/http/request.go: requestURI, proto, ok2 := strings.Cut(rest, " ")
./net/http/cgi/host_test.go: k, v, ok := strings.Cut(trimmedLine, "=")
./net/http/cgi/host.go: header, val, ok := strings.Cut(string(line), ":")
./net/http/cgi/child.go: if k, v, ok := strings.Cut(kv, "="); ok {
./net/http/fs.go: start, end, ok := strings.Cut(ra, "-")
./net/http/cookie.go: name, value, found := strings.Cut(s, "=")
./net/http/cookie.go: name, value, ok := strings.Cut(parts[0], "=")
./net/http/cookie.go: attr, val, _ := strings.Cut(parts[i], "=")
./net/http/cookie.go: part, line, _ = strings.Cut(line, ";")
./net/http/cookie.go: name, val, _ := strings.Cut(part, "=")
./net/http/client_test.go: first, rest, _ := strings.Cut(final, ",")
./net/http/main_test.go: _, stack, _ := strings.Cut(g, "\n")
./net/smtp/smtp.go: k, v, _ := strings.Cut(line, " ")
./net/main_test.go: _, stack, _ := strings.Cut(s, "\n")
./go/types/eval_test.go: before, after, _ := strings.Cut(s, sep)
./go/importer/importer_test.go: compiler, target, _ := strings.Cut(export, ":")
./go/printer/comment.go: line, text, _ = strings.Cut(text, "\n")
./go/printer/printer.go: if p, _, ok := strings.Cut(prefix, "*"); ok {
./go/printer/printer.go: before, _, _ := strings.Cut(last, closing) // closing always present
./go/constant/value_test.go: if ns, ds, ok := strings.Cut(a[1], "/"); ok && kind == token.FLOAT {
./go/constant/value_test.go: if as, bs, ok := strings.Cut(lit, "/"); ok {
./go/version/version.go: v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix.
./go/doc/example_test.go: name, kind, found := strings.Cut(sectionName, ".")
./go/doc/comment/text.go: line, text, _ = strings.Cut(text, "\n")
./go/doc/comment/markdown.go: line, md, _ = strings.Cut(md, "\n")
./go/doc/comment/print.go: line, md, _ = strings.Cut(md, "\n")
./go/doc/comment/print.go: line, rest, ok := strings.Cut(s, "\n")
./go/doc/comment/parse.go: if _, b, ok = strings.Cut(b, "'"); !ok {
./go/doc/comment/parse.go: if _, b, ok = strings.Cut(b, "."); !ok {
./go/doc/headscan.go: inner, s, _ = strings.Cut(s[loc[1]:], html_endh)
./go/build/read_test.go: beforeP, afterP, _ := strings.Cut(tt.in, "ℙ")
./go/build/read_test.go: if beforeD, afterD, ok := strings.Cut(beforeP, "𝔻"); ok {
./go/build/build.go: line, argstr, ok := strings.Cut(strings.TrimSpace(line[4:]), ":")
./go/build/build.go: name, _, _ = strings.Cut(name, ".")
./go/build/vendor_test.go: _, pkg, found = strings.Cut(fullPkg, "/vendor/")
./go/build/build_test.go: errStr, _, _ = strings.Cut(errStr, ";")
./go/build/read.go: path, _, ok = strings.Cut(args[1:], "`")
./go/build/constraint/vers.go: _, v, _ := strings.Cut(z.Tag, "go1.")
./regexp/exec_test.go: loStr, hiStr, _ := strings.Cut(pair, "-")
./regexp/exec_test.go: if _, flag, ok = strings.Cut(flag[1:], ":"); !ok {
./regexp/regexp.go: before, after, ok := strings.Cut(template, "$")
./regexp/syntax/parse.go: lit, t, _ = strings.Cut(t[2:], `\E`)
./archive/tar/writer_test.go: prefix, _, _ = strings.Cut(prefix, "\x00") // Truncate at the NUL terminator
./archive/tar/strconv.go: ss, sn, _ := strings.Cut(s, ".")
./archive/tar/strconv.go: nStr, rest, ok := strings.Cut(s, " ")
./archive/tar/strconv.go: k, v, ok = strings.Cut(rec, "=")
./path/filepath/path.go: part, p, _ = strings.Cut(p, "/")
./runtime/testdata/testprog/traceback_ancestors.go: g, all, _ = strings.Cut(all, "\n\n")
./runtime/testdata/testprog/traceback_ancestors.go: id, _, _ := strings.Cut(strings.TrimPrefix(g, "goroutine "), " ")
./runtime/pprof/proto_test.go: in, out, ok := strings.Cut(tt, "->\n")
./runtime/pprof/pprof_test.go: if _, s, ok = strings.Cut(s, t); !ok {
./runtime/pprof/pprof_test.go: base, kv, ok := strings.Cut(spec, ";")
./runtime/pprof/pprof_test.go: k, v, ok := strings.Cut(kv, "=")
./runtime/pprof/proto.go: loStr, hiStr, ok := strings.Cut(string(addr), "-")
./runtime/trace_cgo_test.go: prefix, tracePath, found := strings.Cut(got, ":")
./runtime/traceback_test.go: _, tb, _ = strings.Cut(tb, "\n")
./runtime/traceback_test.go: line, tb, _ = strings.Cut(tb, "\n")
./runtime/traceback_test.go: funcName, args, found := strings.Cut(line, "(")
./runtime/traceback_system_test.go: _, pcstr, ok := strings.Cut(line, " pc=") // e.g. pc=0x%x
./runtime/debug/mod.go: line, data, ok = strings.Cut(data, newline)
./runtime/debug/mod.go: key, rawValue, ok = strings.Cut(kv, "=")
./internal/testenv/testenv.go: line, goMod, _ = strings.Cut(goMod, "\n")
./internal/testenv/testenv.go: importPath, export, ok := strings.Cut(line, "=")
./internal/zstd/zstd_test.go: want, _, _ := strings.Cut(name, ".")
./encoding/asn1/common.go: part, str, _ = strings.Cut(str, ",")
./encoding/xml/typeinfo.go: if ns, t, ok := strings.Cut(tag, " "); ok {
./encoding/xml/xml.go: } else if space, local, ok := strings.Cut(s, ":"); !ok || space == "" || local == "" {
./encoding/json/tags.go: tag, opt, _ := strings.Cut(tag, ",")
./encoding/json/tags.go: name, s, _ = strings.Cut(s, ",")
./html/template/js.go: mimeType, _, _ = strings.Cut(mimeType, ";")
./html/template/url.go: if protocol, _, ok := strings.Cut(s, ":"); ok && !strings.Contains(protocol, "/") {
./html/template/attr.go: } else if prefix, short, ok := strings.Cut(name, ":"); ok {
./testing/testing_test.go: if name, _, ok := strings.Cut(trimmed, " "); ok {
./log/slog/slogtest_test.go: kv, rest, _ := strings.Cut(s, " ") // assumes exactly one space between attrs
./log/slog/slogtest_test.go: k, value, found := strings.Cut(kv, "=")
./mime/mediatype.go: if major, sub, ok := strings.Cut(t, "/"); !ok {
./mime/mediatype.go: base, _, _ := strings.Cut(v, ";")
./mime/mediatype.go: if baseName, _, ok := strings.Cut(key, "*"); ok {
./mime/encodedword.go: charset, text, _ := strings.Cut(word, "?")
./mime/encodedword.go: encoding, text, _ := strings.Cut(text, "?")
./os/user/lookup_unix.go: u.Name, _, _ = strings.Cut(u.Name, ",")
./os/user/cgo_lookup_unix.go: u.Name, _, _ = strings.Cut(u.Name, ",")
./os/os_test.go: host, _, ok := strings.Cut(hostname, ".")
./os/exec/exec_windows_test.go: k, _, ok := strings.Cut(kv, "=")
./os/exec/exec_test.go: errLine, body, ok := strings.Cut(string(bs), "\n")
./os/exec/exec.go: k, _, ok := strings.Cut(kv, "=")
./text/template/option.go: if key, value, ok := strings.Cut(opt, "="); ok {
Proposal Details
Abstract
This proposal suggests the addition of a new function,
CutByte, to thestringsandbytespackages in the Go standard library. The function aims to simplify the handling of strings and byte slices by cutting them around the first instance of a specified byte separator. This function is designed to offer a more efficient alternative to the existingCutfunction when the separator is a single byte, providing up to a 25% performance improvement in typical use cases.Background
The existing
Cutfunction in the Go standard library has proven to be extremely useful for handling strings and byte slices by simplifying code and replacing multiple standard library functions. However, in scenarios where the separator is known to be a single byte, theCutfunction can be optimized further. The proposedCutBytefunction addresses this by focusing on byte-level operations, which are common in many real-world applications, such as parsing binary protocols or handling ASCII-based text formats.Details
Proposal
We propose adding the following functions:
For the
stringspackage:For the
bytespackage:Rationale
The
CutBytefunction is specifically optimized for cases where the separator is a single byte. In the analysis of Go's main repository and several large-scale Go projects, a significant number of string manipulations involve single-byte separators. The performance benefit ofCutByteoverCutfor these cases is approximately 25%, as measured in benchmarks comparing the two functions under similar conditions.Compatibility
CutByteis a new addition and does not modify any existing interfaces or behavior in the Go standard library. It follows the established patterns and naming conventions of the Go ecosystem, ensuring that it integrates seamlessly with the existing library functions.Implementation
The implementation of
CutByteis straightforward and leverages the existingIndexBytefunction in both thestringsandbytespackages. The proposed functions do not introduce any new dependencies or significant complexities.Conclusion
Adding
CutByteto the Go standard library will provide developers with a more efficient tool for handling common string and byte slice operations involving single-byte separators. This function not only enhances performance but also maintains readability and simplicity, aligning with Go's philosophy of clear and efficient coding practices.