strings.Cut と strings.SplitN はどっちが速いか

2021/10/07に公開

はじめに

https://github.com/golang/go/commit/8e36ab055162efa6f67f3b9ee62f625ac8874901

Go の tip に strings.Cut が入ったのでベンチマークを取った。ちなみに strings.Cut

lhs, rhs, ok := strings.Cut("FooBarBaz", "Bar")
// lhs: Foo
// rhs: Baz
// ok: true

という関数。これを見ると strings.SplitN と変わらんやん?と思ったのでベンチマークを取った。

ベンチマーク

package main_test

import (
	"strings"
	"testing"
)

func BenchmarkCut(b *testing.B) {
	s := "FooBarBaz"
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		lhs, rhs, ok := strings.Cut(s, "Bar")
		if !ok || lhs != "Foo" || rhs != "Baz" {
			b.Fatal("bad!")
		}
	}
}

func BenchmarkSplitN(b *testing.B) {
	s := "FooBarBaz"
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		tok := strings.SplitN(s, "Bar", 2)
		if len(tok) != 2 || tok[0] != "Foo" || tok[1] != "Baz" {
			b.Fatal("bad!")
		}
	}
}
goos: windows
goarch: amd64
pkg: github.com/mattn/go-sandbox/go-strings-cut-benchmark
cpu: AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx  
BenchmarkCut-8      	89285206	        12.47 ns/op	       0 B/op	       0 allocs/op
BenchmarkSplitN-8   	10928264	       104.6 ns/op	      32 B/op	       1 allocs/op
PASS
ok  	github.com/mattn/go-sandbox/go-strings-cut-benchmark	3.468s

結論

strings.Cut

  • 速い (8倍くらい)
  • 安い (allocが無い)
  • うまい (うまい)

Discussion