Closed as not planned
Description
Go 1.24 refactored the map runtime using SwissTable.
When I was using Go 1.24, I found that,
compared to using a for loop to copy a map,
the performance of the built-in maps.Clone was actually worse.
At the same time, in versions prior to Go 1.24,
the performance of maps.Clone was the best.
Below is the code I used for performance testing:
package clone
import (
"maps"
"testing"
)
func clone1(m map[string]string) map[string]string {
if m == nil {
return nil
}
m2 := make(map[string]string, len(m))
for k, v := range m {
m2[k] = v
}
return m2
}
func clone2[M ~map[K]V, K comparable, V any](m M) M {
if m == nil {
return nil
}
m2 := make(M, len(m))
for k, v := range m {
m2[k] = v
}
return m2
}
var m = map[string]string{
"k1": "v1",
"k2": "v2",
"k3": "v3",
"k4": "v4",
}
func BenchmarkClone1(b *testing.B) {
for i := 0; i < b.N; i++ {
clone1(m)
}
}
func BenchmarkClone2(b *testing.B) {
for i := 0; i < b.N; i++ {
clone2(m)
}
}
func BenchmarkStdClone(b *testing.B) {
for i := 0; i < b.N; i++ {
maps.Clone(m)
}
}
Performance test results for different Go versions are as follows:
Go 1.24
goos: darwin
goarch: arm64
pkg: test_code/test_map/clone
cpu: Apple M3 Pro
BenchmarkClone1
BenchmarkClone1-11 16550962 72.64 ns/op
BenchmarkClone2
BenchmarkClone2-11 16820404 71.59 ns/op
BenchmarkStdClone
BenchmarkStdClone-11 9009817 134.1 ns/op
PASS
Process finished with the exit code 0
Go 1.23
goos: darwin
goarch: arm64
pkg: test_code/test_map/clone
cpu: Apple M3 Pro
BenchmarkClone1
BenchmarkClone1-11 15726506 77.62 ns/op
BenchmarkClone2
BenchmarkClone2-11 14940602 80.03 ns/op
BenchmarkStdClone
BenchmarkStdClone-11 20451465 59.58 ns/op
PASS
Process finished with the exit code 0
The results for Go 1.22 and Go 1.21 are similar to Go 1.23.