-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b35a487
commit d2e9f90
Showing
7 changed files
with
1,910 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
run: build bench stat | ||
|
||
build: | ||
go test -c -o natsort-bench.exec | ||
|
||
bench: | ||
time ./natsort-bench.exec \ | ||
-test.v -test.benchmem \ | ||
-test.bench ^Benchmark \ | ||
-test.count 3 \ | ||
-test.run ^$ | tee bench.txt | ||
|
||
stat: | ||
benchstat bench.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
goos: darwin | ||
goarch: arm64 | ||
pkg: github.com/cristaloleg/benches/natsort | ||
BenchmarkStdlib_Strings | ||
BenchmarkStdlib_Strings/small | ||
BenchmarkStdlib_Strings/small-10 561956 2117 ns/op 24 B/op 1 allocs/op | ||
BenchmarkStdlib_Strings/small-10 547368 2121 ns/op 24 B/op 1 allocs/op | ||
BenchmarkStdlib_Strings/small-10 545804 2125 ns/op 24 B/op 1 allocs/op | ||
BenchmarkStdlib_Strings/huge | ||
BenchmarkStdlib_Strings/huge-10 6225 188029 ns/op 24 B/op 1 allocs/op | ||
BenchmarkStdlib_Strings/huge-10 6210 188691 ns/op 24 B/op 1 allocs/op | ||
BenchmarkStdlib_Strings/huge-10 5698 187595 ns/op 24 B/op 1 allocs/op | ||
BenchmarkCristalhq_Sort | ||
BenchmarkCristalhq_Sort/small | ||
BenchmarkCristalhq_Sort/small-10 316620 3794 ns/op 0 B/op 0 allocs/op | ||
BenchmarkCristalhq_Sort/small-10 314504 3780 ns/op 0 B/op 0 allocs/op | ||
BenchmarkCristalhq_Sort/small-10 310911 3792 ns/op 0 B/op 0 allocs/op | ||
BenchmarkCristalhq_Sort/huge | ||
BenchmarkCristalhq_Sort/huge-10 2227 522022 ns/op 0 B/op 0 allocs/op | ||
BenchmarkCristalhq_Sort/huge-10 2328 525377 ns/op 0 B/op 0 allocs/op | ||
BenchmarkCristalhq_Sort/huge-10 2269 519937 ns/op 0 B/op 0 allocs/op | ||
BenchmarkCristalhq_Slice | ||
BenchmarkCristalhq_Slice/small | ||
BenchmarkCristalhq_Slice/small-10 295246 4081 ns/op 24 B/op 1 allocs/op | ||
BenchmarkCristalhq_Slice/small-10 294901 4051 ns/op 24 B/op 1 allocs/op | ||
BenchmarkCristalhq_Slice/small-10 295615 4119 ns/op 24 B/op 1 allocs/op | ||
BenchmarkCristalhq_Slice/huge | ||
BenchmarkCristalhq_Slice/huge-10 2246 537975 ns/op 24 B/op 1 allocs/op | ||
BenchmarkCristalhq_Slice/huge-10 2256 537370 ns/op 24 B/op 1 allocs/op | ||
BenchmarkCristalhq_Slice/huge-10 2218 532765 ns/op 24 B/op 1 allocs/op | ||
BenchmarkFacette_Sort | ||
BenchmarkFacette_Sort/small | ||
BenchmarkFacette_Sort/small-10 6409 184176 ns/op 101048 B/op 1810 allocs/op | ||
BenchmarkFacette_Sort/small-10 6489 180198 ns/op 101429 B/op 1815 allocs/op | ||
BenchmarkFacette_Sort/small-10 6244 182682 ns/op 101242 B/op 1812 allocs/op | ||
BenchmarkFacette_Sort/huge | ||
BenchmarkFacette_Sort/huge-10 45 25645570 ns/op 16170764 B/op 323866 allocs/op | ||
BenchmarkFacette_Sort/huge-10 43 25996568 ns/op 16258429 B/op 325554 allocs/op | ||
BenchmarkFacette_Sort/huge-10 44 25354756 ns/op 16208050 B/op 324899 allocs/op | ||
BenchmarkMaruel_Sort | ||
BenchmarkMaruel_Sort/small | ||
BenchmarkMaruel_Sort/small-10 247838 4673 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMaruel_Sort/small-10 250066 4685 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMaruel_Sort/small-10 250335 4690 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMaruel_Sort/huge | ||
BenchmarkMaruel_Sort/huge-10 1462 808731 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMaruel_Sort/huge-10 1460 816428 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMaruel_Sort/huge-10 1400 827159 ns/op 24 B/op 1 allocs/op | ||
BenchmarkDangogh_Slice | ||
BenchmarkDangogh_Slice/small | ||
BenchmarkDangogh_Slice/small-10 91945 13080 ns/op 24 B/op 1 allocs/op | ||
BenchmarkDangogh_Slice/small-10 89635 13014 ns/op 24 B/op 1 allocs/op | ||
BenchmarkDangogh_Slice/small-10 92401 13013 ns/op 24 B/op 1 allocs/op | ||
BenchmarkDangogh_Slice/huge | ||
BenchmarkDangogh_Slice/huge-10 738 1639175 ns/op 24 B/op 1 allocs/op | ||
BenchmarkDangogh_Slice/huge-10 728 1658934 ns/op 24 B/op 1 allocs/op | ||
BenchmarkDangogh_Slice/huge-10 724 1647764 ns/op 24 B/op 1 allocs/op | ||
BenchmarkEvie404_Slice | ||
BenchmarkEvie404_Slice/small | ||
BenchmarkEvie404_Slice/small-10 95402 12068 ns/op 24 B/op 1 allocs/op | ||
BenchmarkEvie404_Slice/small-10 98350 12067 ns/op 24 B/op 1 allocs/op | ||
BenchmarkEvie404_Slice/small-10 96961 12054 ns/op 24 B/op 1 allocs/op | ||
BenchmarkEvie404_Slice/huge | ||
BenchmarkEvie404_Slice/huge-10 1470 817867 ns/op 24 B/op 1 allocs/op | ||
BenchmarkEvie404_Slice/huge-10 1480 806769 ns/op 24 B/op 1 allocs/op | ||
BenchmarkEvie404_Slice/huge-10 1456 805209 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMiraclesu_Slice | ||
BenchmarkMiraclesu_Slice/small | ||
BenchmarkMiraclesu_Slice/small-10 105171 11270 ns/op 57 B/op 5 allocs/op | ||
BenchmarkMiraclesu_Slice/small-10 106788 11159 ns/op 57 B/op 5 allocs/op | ||
BenchmarkMiraclesu_Slice/small-10 107000 11291 ns/op 57 B/op 5 allocs/op | ||
BenchmarkMiraclesu_Slice/huge | ||
BenchmarkMiraclesu_Slice/huge-10 862 1387731 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMiraclesu_Slice/huge-10 861 1378709 ns/op 24 B/op 1 allocs/op | ||
BenchmarkMiraclesu_Slice/huge-10 865 1392451 ns/op 24 B/op 1 allocs/op | ||
BenchmarkImmortal_Slice | ||
BenchmarkImmortal_Slice/small | ||
BenchmarkImmortal_Slice/small-10 55617 20679 ns/op 12499 B/op 385 allocs/op | ||
BenchmarkImmortal_Slice/small-10 58698 20083 ns/op 12494 B/op 384 allocs/op | ||
BenchmarkImmortal_Slice/small-10 58990 20010 ns/op 12495 B/op 384 allocs/op | ||
BenchmarkImmortal_Slice/huge | ||
BenchmarkImmortal_Slice/huge-10 782 1515601 ns/op 950145 B/op 33556 allocs/op | ||
BenchmarkImmortal_Slice/huge-10 780 1525203 ns/op 951441 B/op 33601 allocs/op | ||
BenchmarkImmortal_Slice/huge-10 789 1498044 ns/op 950063 B/op 33555 allocs/op | ||
PASS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module github.com/cristaloleg/benches/natsort | ||
|
||
go 1.20 | ||
|
||
require ( | ||
github.com/cristalhq/natsort v0.1.1 | ||
github.com/dangogh/naturally v0.1.1 | ||
github.com/evie404/natsort v0.0.0-20180124032556-f194e6bd5b0c | ||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb | ||
github.com/immortal/natcasesort v0.0.0-20180922190600-53ad4be8bc1a | ||
github.com/maruel/natural v1.1.0 | ||
github.com/miraclesu/natsort v0.0.0-20160121124727-836e59d384de | ||
) | ||
|
||
require github.com/smartystreets/goconvey v1.8.0 // indirect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
github.com/cristalhq/natsort v0.1.1 h1:UlPHSkP+Tx2f0wgoZS3N3U29nO3NF7lHvhEKuQr8LpY= | ||
github.com/cristalhq/natsort v0.1.1/go.mod h1:cGdtrXl4O1ycmnwdnSBWgmTzZ9WP4i8ca2LH/QupN0Y= | ||
github.com/dangogh/naturally v0.1.1 h1:q9j9n4Ij/cjZv7MOUj+871HTrCJE3ZJeoJrw5CjPrC0= | ||
github.com/dangogh/naturally v0.1.1/go.mod h1:pmGmUAFR+GoKRXHpf/K5Hs2JP0o8oatc3t0NeVjrf8U= | ||
github.com/evie404/natsort v0.0.0-20180124032556-f194e6bd5b0c h1:DNvN+Lov05ao9/haEzCTzJDfIHL/F4E3DBsDUMnjpYs= | ||
github.com/evie404/natsort v0.0.0-20180124032556-f194e6bd5b0c/go.mod h1:+D05cmtvIC2Mc7z7x+AM82AAbaaBlUI9fMHJomz77qI= | ||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= | ||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= | ||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= | ||
github.com/immortal/natcasesort v0.0.0-20180922190600-53ad4be8bc1a h1:xGCNWvZqUk/9l1ytDVzZHLAadyrB6My8AoG6ksxWbDU= | ||
github.com/immortal/natcasesort v0.0.0-20180922190600-53ad4be8bc1a/go.mod h1:wrlf+Cc7o4fqKniC+4ebBmr6sJ8eeOjx5588f/4RgIU= | ||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= | ||
github.com/maruel/natural v1.1.0 h1:2z1NgP/Vae+gYrtC0VuvrTJ6U35OuyUqDdfluLqMWuQ= | ||
github.com/maruel/natural v1.1.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ= | ||
github.com/miraclesu/natsort v0.0.0-20160121124727-836e59d384de h1:ZTLp5p4MzSKh9Is0s+l/J7qQiY4c3yKA98J5z1qcyv0= | ||
github.com/miraclesu/natsort v0.0.0-20160121124727-836e59d384de/go.mod h1:hYCDR4MVndk4vkatvVgNzw27cfxJH+fLFSMFdjdMXmQ= | ||
github.com/smartystreets/assertions v1.13.1 h1:Ef7KhSmjZcK6AVf9YbJdvPYG9avaF0ZxudX+ThRdWfU= | ||
github.com/smartystreets/goconvey v1.8.0 h1:Oi49ha/2MURE0WexF052Z0m+BNSGirfjg5RL+JXWq3w= | ||
github.com/smartystreets/goconvey v1.8.0/go.mod h1:EdX8jtrTIj26jmjCOVNMVSIYAtgexqXKHOXW2Dx9JLg= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
package natsort_test | ||
|
||
import ( | ||
"bytes" | ||
_ "embed" | ||
"math/rand" | ||
"sort" | ||
"testing" | ||
|
||
cristalhq "github.com/cristalhq/natsort" | ||
dangogh "github.com/dangogh/naturally" | ||
evie404 "github.com/evie404/natsort" | ||
facette "github.com/facette/natsort" | ||
immortal "github.com/immortal/natcasesort" | ||
maruel "github.com/maruel/natural" | ||
miraclesu "github.com/miraclesu/natsort" | ||
) | ||
|
||
func BenchmarkStdlib_Strings(b *testing.B) { | ||
bench(b, "small", smallList, func(list []string) { | ||
sort.Strings(list) | ||
}) | ||
|
||
bench(b, "huge", tagsList, func(list []string) { | ||
sort.Strings(list) | ||
}) | ||
|
||
// no need to checkResult(..) because stdlib sort is correct | ||
// and result is sorted in lexicographical order, not natural | ||
} | ||
|
||
func BenchmarkCristalhq_Sort(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
cristalhq.Sort(list) | ||
}) | ||
checkResult(b, data) | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
cristalhq.Sort(list) | ||
}) | ||
checkResult(b, data) | ||
} | ||
|
||
func BenchmarkCristalhq_Slice(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
sort.Sort(cristalhq.Slice[string](list)) | ||
}) | ||
checkResult(b, data) | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
sort.Sort(cristalhq.Slice[string](list)) | ||
}) | ||
checkResult(b, data) | ||
} | ||
|
||
func BenchmarkFacette_Sort(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
facette.Sort(list) | ||
}) | ||
checkResult(b, data) | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
facette.Sort(list) | ||
}) | ||
// no check, small variance in the result | ||
} | ||
|
||
func BenchmarkMaruel_Sort(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
sort.Sort(maruel.StringSlice(list)) | ||
}) | ||
checkResult(b, data) | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
sort.Sort(maruel.StringSlice(list)) | ||
}) | ||
checkResult(b, data) | ||
} | ||
|
||
func BenchmarkDangogh_Slice(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
sort.Sort(dangogh.StringSlice(list)) | ||
}) | ||
// no check, incorrect result | ||
_ = data | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
sort.Sort(dangogh.StringSlice(list)) | ||
}) | ||
// no check, incorrect result | ||
} | ||
|
||
func BenchmarkEvie404_Slice(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
evie404.Strings(list) | ||
}) | ||
checkResult(b, data) | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
evie404.Strings(list) | ||
}) | ||
checkResult(b, data) | ||
} | ||
|
||
func BenchmarkMiraclesu_Slice(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
miraclesu.Sort(list) | ||
}) | ||
// no check, incorrect result | ||
_ = data | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
miraclesu.Sort(list) | ||
}) | ||
// no check, incorrect result | ||
} | ||
|
||
func BenchmarkImmortal_Slice(b *testing.B) { | ||
data := bench(b, "small", smallList, func(list []string) { | ||
sort.Sort(immortal.Sort(list)) | ||
}) | ||
// no check, incorrect result | ||
_ = data | ||
|
||
data = bench(b, "huge", tagsList, func(list []string) { | ||
sort.Sort(immortal.Sort(list)) | ||
}) | ||
// no check, incorrect result | ||
} | ||
|
||
func bench(b *testing.B, name string, input []string, fn func(list []string)) []string { | ||
b.Helper() | ||
|
||
data := make([]string, len(input)) | ||
r := rand.New(rand.NewSource(69420)) | ||
copy(data, input) | ||
|
||
b.Run(name, func(b *testing.B) { | ||
for i := 0; i < b.N; i++ { | ||
r.Shuffle(len(data), func(i, j int) { | ||
data[i], data[j] = data[j], data[i] | ||
}) | ||
fn(data) | ||
} | ||
}) | ||
return data | ||
} | ||
|
||
func checkResult(b *testing.B, list []string) { | ||
b.Helper() | ||
|
||
ok := sort.SliceIsSorted(list, func(i, j int) bool { | ||
return cristalhq.Less(list[i], list[j]) | ||
}) | ||
if !ok { | ||
b.Errorf("not sorted %+v", list) | ||
} | ||
} | ||
|
||
var ( | ||
//go:embed testdata/small.txt | ||
smallFile []byte | ||
|
||
//go:embed testdata/aws-sdk-go-tags.txt | ||
tagsFile []byte | ||
) | ||
|
||
var ( | ||
smallList []string | ||
tagsList []string | ||
) | ||
|
||
func init() { | ||
smallList = readFile(smallFile) | ||
tagsList = readFile(tagsFile) | ||
} | ||
|
||
func readFile(raw []byte) []string { | ||
lines := bytes.Split(raw, []byte{'\n'}) | ||
res := make([]string, len(lines)) | ||
|
||
for i, line := range lines { | ||
res[i] = string(line) | ||
} | ||
return res | ||
} |
Oops, something went wrong.