Skip to content

Instantly share code, notes, and snippets.

@Deleplace
Created August 25, 2022 09:16
Show Gist options
  • Save Deleplace/067ed63b3c8db5975f21bd4eb0488efd to your computer and use it in GitHub Desktop.
Save Deleplace/067ed63b3c8db5975f21bd4eb0488efd to your computer and use it in GitHub Desktop.
Benchmark: delete from slice vs. delete from slice and zero the discarded right tail
package slices
import "testing"
func delete[S ~[]E, E any](s S, i, j int) S {
_ = s[i:j] // bound check
return append(s[:i], s[j:]...)
}
func deleteAndZero[S ~[]E, E any](s S, i, j int) S {
_ = s[i:j] // bound check
var zero E
result := append(s[:i], s[j:]...)
for k := len(s) - (j - i); k < len(s); k++ {
s[k] = zero // Let the GC do its work
}
return result
}
//
// int
//
func BenchmarkDelete_int_1_50(b *testing.B) {
a := make([]int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 31)
}
}
func BenchmarkDeleteAndZero_int_1_50(b *testing.B) {
a := make([]int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 31)
}
}
func BenchmarkDelete_int_1_5000(b *testing.B) {
a := make([]int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 3001)
}
}
func BenchmarkDeleteAndZero_int_1_5000(b *testing.B) {
a := make([]int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 3001)
}
}
func BenchmarkDelete_int_10_50(b *testing.B) {
a := make([]int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 40)
}
}
func BenchmarkDeleteAndZero_int_10_50(b *testing.B) {
a := make([]int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 40)
}
}
func BenchmarkDelete_int_1000_5000(b *testing.B) {
a := make([]int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 4000)
}
}
func BenchmarkDeleteAndZero_int_1000_5000(b *testing.B) {
a := make([]int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 4000)
}
}
//
// *int
//
func BenchmarkDelete_pint_1_50(b *testing.B) {
a := make([]*int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 31)
}
}
func BenchmarkDeleteAndZero_pint_1_50(b *testing.B) {
a := make([]*int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 31)
}
}
func BenchmarkDelete_pint_1_5000(b *testing.B) {
a := make([]*int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 3001)
}
}
func BenchmarkDeleteAndZero_pint_1_5000(b *testing.B) {
a := make([]*int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 3001)
}
}
func BenchmarkDelete_pint_10_50(b *testing.B) {
a := make([]*int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 40)
}
}
func BenchmarkDeleteAndZero_pint_10_50(b *testing.B) {
a := make([]*int, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 40)
}
}
func BenchmarkDelete_pint_1000_5000(b *testing.B) {
a := make([]*int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 4000)
}
}
func BenchmarkDeleteAndZero_pint_1000_5000(b *testing.B) {
a := make([]*int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 4000)
}
}
//
// [64]byte
//
type data [64]byte
func BenchmarkDelete_data_1_50(b *testing.B) {
a := make([]data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 31)
}
}
func BenchmarkDeleteAndZero_data_1_50(b *testing.B) {
a := make([]data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 31)
}
}
func BenchmarkDelete_data_1_5000(b *testing.B) {
a := make([]data, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 3001)
}
}
func BenchmarkDeleteAndZero_data_1_5000(b *testing.B) {
a := make([]data, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 3001)
}
}
func BenchmarkDelete_data_10_50(b *testing.B) {
a := make([]data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 40)
}
}
func BenchmarkDeleteAndZero_data_10_50(b *testing.B) {
a := make([]data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 40)
}
}
func BenchmarkDelete_data_1000_5000(b *testing.B) {
a := make([]data, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 4000)
}
}
func BenchmarkDeleteAndZero_data_1000_5000(b *testing.B) {
a := make([]data, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 4000)
}
}
//
// *[64]byte
//
func BenchmarkDelete_pdata_1_50(b *testing.B) {
a := make([]*data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 31)
}
}
func BenchmarkDeleteAndZero_pdata_1_50(b *testing.B) {
a := make([]*data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 31)
}
}
func BenchmarkDelete_pdata_1_5000(b *testing.B) {
a := make([]*data, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 3001)
}
}
func BenchmarkDeleteAndZero_pdata_1_5000(b *testing.B) {
a := make([]*data, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 3001)
}
}
func BenchmarkDelete_pdata_10_50(b *testing.B) {
a := make([]*data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 30, 40)
}
}
func BenchmarkDeleteAndZero_pdata_10_50(b *testing.B) {
a := make([]*data, 50)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 30, 40)
}
}
func BenchmarkDelete_pdata_1000_5000(b *testing.B) {
a := make([]*data, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = delete(a, 3000, 4000)
}
}
func BenchmarkDeleteAndZero_pdata_1000_5000(b *testing.B) {
a := make([]*int, 5000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = deleteAndZero(a, 3000, 4000)
}
}
@Deleplace
Copy link
Author

Results on my workstation:

% go test -bench=.
goos: darwin
goarch: amd64
pkg: slices-delete-benchmark
cpu: VirtualApple @ 2.50GHz
BenchmarkDelete_int_1_50-10                  	150132241	         8.069 ns/op
BenchmarkDeleteAndZero_int_1_50-10           	143628110	         8.319 ns/op
BenchmarkDelete_int_1_5000-10                	 1658834	       729.4 ns/op
BenchmarkDeleteAndZero_int_1_5000-10         	 1657263	       726.1 ns/op
BenchmarkDelete_int_10_50-10                 	227920299	         5.463 ns/op
BenchmarkDeleteAndZero_int_10_50-10          	140019034	         8.662 ns/op
BenchmarkDelete_int_1000_5000-10             	 3260648	       382.9 ns/op
BenchmarkDeleteAndZero_int_1000_5000-10      	 1686759	       718.6 ns/op
BenchmarkDelete_pint_1_50-10                 	138902164	         8.608 ns/op
BenchmarkDeleteAndZero_pint_1_50-10          	125234313	         9.494 ns/op
BenchmarkDelete_pint_1_5000-10               	 1650751	       724.8 ns/op
BenchmarkDeleteAndZero_pint_1_5000-10        	 1639924	       737.2 ns/op
BenchmarkDelete_pint_10_50-10                	163371553	         7.290 ns/op
BenchmarkDeleteAndZero_pint_10_50-10         	90488634	        13.12 ns/op
BenchmarkDelete_pint_1000_5000-10            	 3256309	       368.5 ns/op
BenchmarkDeleteAndZero_pint_1000_5000-10     	 1000000	      1014 ns/op
BenchmarkDelete_data_1_50-10                 	46486027	        26.14 ns/op
BenchmarkDeleteAndZero_data_1_50-10          	39360554	        30.77 ns/op
BenchmarkDelete_data_1_5000-10               	  205742	      5781 ns/op
BenchmarkDeleteAndZero_data_1_5000-10        	  208984	      5727 ns/op
BenchmarkDelete_data_10_50-10                	81428156	        14.36 ns/op
BenchmarkDeleteAndZero_data_10_50-10         	42188283	        28.38 ns/op
BenchmarkDelete_data_1000_5000-10            	  411010	      2893 ns/op
BenchmarkDeleteAndZero_data_1000_5000-10     	  315439	      3824 ns/op
BenchmarkDelete_pdata_1_50-10                	139871204	         8.569 ns/op
BenchmarkDeleteAndZero_pdata_1_50-10         	126247327	         9.491 ns/op
BenchmarkDelete_pdata_1_5000-10              	 1651886	       726.7 ns/op
BenchmarkDeleteAndZero_pdata_1_5000-10       	 1647685	       728.0 ns/op
BenchmarkDelete_pdata_10_50-10               	164709849	         7.260 ns/op
BenchmarkDeleteAndZero_pdata_10_50-10        	90208322	        13.13 ns/op
BenchmarkDelete_pdata_1000_5000-10           	 3252710	       367.8 ns/op
BenchmarkDeleteAndZero_pdata_1000_5000-10    	 1000000	      1012 ns/op
PASS
ok  	slices-delete-benchmark	53.831s

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