Skip to content

Instantly share code, notes, and snippets.

@Deleplace
Last active August 26, 2022 20:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Deleplace/838d23bfdb710fc8b53547360ea6b5f8 to your computer and use it in GitHub Desktop.
Save Deleplace/838d23bfdb710fc8b53547360ea6b5f8 to your computer and use it in GitHub Desktop.
Benchmark deleting the parts of a slice, for various slice lengths
package delete
import (
"fmt"
"testing"
"golang.org/x/exp/slices"
)
func BenchmarkDeleteLast(b *testing.B) {
for k := 10; k < 10_000_000; k *= 10 {
name := fmt.Sprintf("DeleteLast_1_%d", k)
b.Run(name, func(b *testing.B) {
s := make([]byte, k)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sink = slices.Delete(s, k-1, k)
}
})
}
}
func BenchmarkDeleteLast1000(b *testing.B) {
for k := 1000; k < 10_000_000; k *= 10 {
name := fmt.Sprintf("DeleteLast_1000_%d", k)
b.Run(name, func(b *testing.B) {
s := make([]byte, k)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sink = slices.Delete(s, k-1, k)
}
})
}
}
func BenchmarkDeleteMiddle(b *testing.B) {
for k := 10; k < 10_000_000; k *= 10 {
name := fmt.Sprintf("DeleteMiddle_1_%d", k)
b.Run(name, func(b *testing.B) {
s := make([]byte, k)
m := k / 2
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sink = slices.Delete(s, m, m+1)
}
})
}
}
// Prevent optimizing things away
var Sink []byte
@Deleplace
Copy link
Author

Results on my workstation:

% go test -bench=.
goos: darwin
goarch: amd64
pkg: delete
cpu: VirtualApple @ 2.50GHz
BenchmarkDeleteLast/DeleteLast_1_10-10         	300007938	         4.004 ns/op
BenchmarkDeleteLast/DeleteLast_1_100-10        	299902094	         4.002 ns/op
BenchmarkDeleteLast/DeleteLast_1_1000-10       	300838335	         3.991 ns/op
BenchmarkDeleteLast/DeleteLast_1_10000-10      	301185762	         3.996 ns/op
BenchmarkDeleteLast/DeleteLast_1_100000-10     	300077894	         3.998 ns/op
BenchmarkDeleteLast/DeleteLast_1_1000000-10    	301128510	         4.107 ns/op
BenchmarkDeleteLast1000/DeleteLast_1000_1000-10         	296975397	         3.999 ns/op
BenchmarkDeleteLast1000/DeleteLast_1000_10000-10        	299375800	         4.025 ns/op
BenchmarkDeleteLast1000/DeleteLast_1000_100000-10       	300890383	         4.006 ns/op
BenchmarkDeleteLast1000/DeleteLast_1000_1000000-10      	300420024	         4.008 ns/op
BenchmarkDeleteMiddle/DeleteMiddle_1_10-10              	225945192	         5.314 ns/op
BenchmarkDeleteMiddle/DeleteMiddle_1_100-10             	218974356	         5.431 ns/op
BenchmarkDeleteMiddle/DeleteMiddle_1_1000-10            	96280815	        12.51 ns/op
BenchmarkDeleteMiddle/DeleteMiddle_1_10000-10           	 5246284	       228.0 ns/op
BenchmarkDeleteMiddle/DeleteMiddle_1_100000-10          	  542217	      2215 ns/op
BenchmarkDeleteMiddle/DeleteMiddle_1_1000000-10         	   53709	     22304 ns/op
PASS
ok  	delete	25.773s

The first part DeleteLast shows that deleting the end of a slice is constant time, regardless the size of the slice, and regardless the number of elements to delete.

The second part DeleteMiddle is consistent with the amount of work needed to shift half of the slice to the left, which is O(len(s)-j).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment