Skip to content

Instantly share code, notes, and snippets.

@earthboundkid
Forked from jszwec/bench_test.go
Last active July 24, 2024 13:16
Show Gist options
  • Save earthboundkid/af8e9b612f7bc2ce1af419f2a7975ffc to your computer and use it in GitHub Desktop.
Save earthboundkid/af8e9b612f7bc2ce1af419f2a7975ffc to your computer and use it in GitHub Desktop.
package csvutil_test
import (
"bytes"
"encoding/csv"
"testing"
ebcsv "github.com/earthboundkid/csv/v2"
"github.com/gocarina/gocsv"
"github.com/jszwec/csvutil"
"github.com/yunabe/easycsv"
)
func BenchmarkUnmarshal(b *testing.B) {
type A struct {
A int `csv:"a" name:"a"`
B float64 `csv:"b" name:"b"`
C string `csv:"c" name:"c"`
D int64 `csv:"d" name:"d"`
E int8 `csv:"e" name:"e"`
F float32 `csv:"f" name:"f"`
G float32 `csv:"g" name:"g"`
H float32 `csv:"h" name:"h"`
I string `csv:"i" name:"i"`
J int `csv:"j" name:"j"`
}
fixture := []struct {
desc string
records int
}{
{
desc: "1 record",
records: 1,
},
{
desc: "10 records",
records: 10,
},
{
desc: "100 records",
records: 100,
},
{
desc: "1000 records",
records: 1000,
},
{
desc: "10000 records",
records: 10000,
},
{
desc: "100000 records",
records: 100000,
},
}
tests := []struct {
desc string
fn func([]byte, *testing.B)
}{
{
desc: "csv.Scan",
fn: func(data []byte, b *testing.B) {
var a A
opts := ebcsv.Options{Reader: bytes.NewReader(data)}
for err := range ebcsv.Scan(opts, &a) {
if err != nil {
b.Error(err)
}
}
},
},
{
desc: "csv.ScanAll",
fn: func(data []byte, b *testing.B) {
opts := ebcsv.Options{Reader: bytes.NewReader(data)}
as, err := ebcsv.ScanAll[A](opts)
if err != nil {
b.Error(err)
}
_ = as
},
},
{
desc: "csvutil.Unmarshal",
fn: func(data []byte, b *testing.B) {
var a []A
if err := csvutil.Unmarshal(data, &a); err != nil {
b.Error(err)
}
},
},
{
desc: "gocsv.Unmarshal",
fn: func(data []byte, b *testing.B) {
var a []A
if err := gocsv.UnmarshalBytes(data, &a); err != nil {
b.Error(err)
}
},
},
{
desc: "easycsv.ReadAll",
fn: func(data []byte, b *testing.B) {
r := easycsv.NewReader(bytes.NewReader(data))
var a []A
if err := r.ReadAll(&a); err != nil {
b.Error(err)
}
},
},
}
for _, t := range tests {
b.Run(t.desc, func(b *testing.B) {
for _, f := range fixture {
b.Run(f.desc, func(b *testing.B) {
data := genData(f.records)
b.ResetTimer()
for range b.N {
t.fn(data, b)
}
})
}
})
}
}
func genData(records int) []byte {
header := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}
record := []string{"1", "2.5", "foo", "6", "7", "8", "9", "10", "bar", "10"}
var buf bytes.Buffer
w := csv.NewWriter(&buf)
w.Write(header)
for i := 0; i < records; i++ {
w.Write(record)
}
w.Flush()
if err := w.Error(); err != nil {
panic(err)
}
return buf.Bytes()
}
Running tool: go1.23rc1 test -benchmem -run=^$ -bench ^BenchmarkUnmarshal$ github.com/earthboundkid/csv/v2
goos: darwin
goarch: arm64
pkg: github.com/earthboundkid/csv/v2
cpu: Apple M2
BenchmarkUnmarshal/csv.Scan/1_record-8 607689 1956 ns/op 6220 B/op 43 allocs/op
BenchmarkUnmarshal/csv.Scan/10_records-8 313846 3799 ns/op 6436 B/op 52 allocs/op
BenchmarkUnmarshal/csv.Scan/100_records-8 54745 22090 ns/op 8596 B/op 142 allocs/op
BenchmarkUnmarshal/csv.Scan/1000_records-8 5835 205941 ns/op 30197 B/op 1042 allocs/op
BenchmarkUnmarshal/csv.Scan/10000_records-8 589 2098079 ns/op 246200 B/op 10042 allocs/op
BenchmarkUnmarshal/csv.Scan/100000_records-8 52 20856365 ns/op 2406225 B/op 100042 allocs/op
BenchmarkUnmarshal/csv.ScanAll/1_record-8 586586 2051 ns/op 6412 B/op 48 allocs/op
BenchmarkUnmarshal/csv.ScanAll/10_records-8 279940 4279 ns/op 9220 B/op 61 allocs/op
BenchmarkUnmarshal/csv.ScanAll/100_records-8 49363 24259 ns/op 32884 B/op 154 allocs/op
BenchmarkUnmarshal/csv.ScanAll/1000_records-8 5552 218397 ns/op 210134 B/op 1057 allocs/op
BenchmarkUnmarshal/csv.ScanAll/10000_records-8 486 2682257 ns/op 3825818 B/op 10065 allocs/op
BenchmarkUnmarshal/csv.ScanAll/100000_records-8 48 24641765 ns/op 45520411 B/op 100075 allocs/op
BenchmarkUnmarshal/csvutil.Unmarshal/1_record-8 467376 2615 ns/op 8132 B/op 31 allocs/op
BenchmarkUnmarshal/csvutil.Unmarshal/10_records-8 195751 6151 ns/op 9084 B/op 40 allocs/op
BenchmarkUnmarshal/csvutil.Unmarshal/100_records-8 29284 41184 ns/op 18540 B/op 130 allocs/op
BenchmarkUnmarshal/csvutil.Unmarshal/1000_records-8 3079 388850 ns/op 113869 B/op 1030 allocs/op
BenchmarkUnmarshal/csvutil.Unmarshal/10000_records-8 310 3858911 ns/op 1050768 B/op 10030 allocs/op
BenchmarkUnmarshal/csvutil.Unmarshal/100000_records-8 30 39798510 ns/op 10411531 B/op 100030 allocs/op
BenchmarkUnmarshal/gocsv.Unmarshal/1_record-8 322330 3686 ns/op 7410 B/op 55 allocs/op
BenchmarkUnmarshal/gocsv.Unmarshal/10_records-8 99259 12141 ns/op 13866 B/op 220 allocs/op
BenchmarkUnmarshal/gocsv.Unmarshal/100_records-8 13046 92606 ns/op 77627 B/op 1843 allocs/op
BenchmarkUnmarshal/gocsv.Unmarshal/1000_records-8 1300 905362 ns/op 700003 B/op 18046 allocs/op
BenchmarkUnmarshal/gocsv.Unmarshal/10000_records-8 124 9112158 ns/op 7306464 B/op 180053 allocs/op
BenchmarkUnmarshal/gocsv.Unmarshal/100000_records-8 12 93063004 ns/op 76180364 B/op 1800063 allocs/op
BenchmarkUnmarshal/easycsv.ReadAll/1_record-8 189766 6278 ns/op 9162 B/op 96 allocs/op
BenchmarkUnmarshal/easycsv.ReadAll/10_records-8 38257 31259 ns/op 22301 B/op 496 allocs/op
BenchmarkUnmarshal/easycsv.ReadAll/100_records-8 4117 276691 ns/op 149274 B/op 4459 allocs/op
BenchmarkUnmarshal/easycsv.ReadAll/1000_records-8 440 2726610 ns/op 1359471 B/op 44062 allocs/op
BenchmarkUnmarshal/easycsv.ReadAll/10000_records-8 43 27644269 ns/op 15306362 B/op 440070 allocs/op
BenchmarkUnmarshal/easycsv.ReadAll/100000_records-8 4 280142000 ns/op 160225896 B/op 4400080 allocs/op
PASS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment