Skip to content

Commit 463ce36

Browse files
authored
test: add benchmark tests for writer (#74)
1 parent 7e116c6 commit 463ce36

2 files changed

Lines changed: 266 additions & 0 deletions

File tree

benchmark_test.go

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,212 @@ func BenchmarkWriteQuotedField_Long(b *testing.B) {
355355
}
356356
}
357357

358+
// =============================================================================
359+
// WriteAll Benchmarks - Simple CSV
360+
// =============================================================================
361+
362+
func BenchmarkWriteAll_Simple_1K_Stdlib(b *testing.B) {
363+
records := generateSimpleRecords(1000, 10)
364+
for b.Loop() {
365+
var buf bytes.Buffer
366+
w := csv.NewWriter(&buf)
367+
_ = w.WriteAll(records)
368+
}
369+
}
370+
371+
func BenchmarkWriteAll_Simple_1K_SIMD(b *testing.B) {
372+
records := generateSimpleRecords(1000, 10)
373+
for b.Loop() {
374+
var buf bytes.Buffer
375+
w := NewWriter(&buf)
376+
_ = w.WriteAll(records)
377+
}
378+
}
379+
380+
func BenchmarkWriteAll_Simple_10K_Stdlib(b *testing.B) {
381+
records := generateSimpleRecords(10000, 10)
382+
for b.Loop() {
383+
var buf bytes.Buffer
384+
w := csv.NewWriter(&buf)
385+
_ = w.WriteAll(records)
386+
}
387+
}
388+
389+
func BenchmarkWriteAll_Simple_10K_SIMD(b *testing.B) {
390+
records := generateSimpleRecords(10000, 10)
391+
for b.Loop() {
392+
var buf bytes.Buffer
393+
w := NewWriter(&buf)
394+
_ = w.WriteAll(records)
395+
}
396+
}
397+
398+
func BenchmarkWriteAll_Simple_100K_Stdlib(b *testing.B) {
399+
records := generateSimpleRecords(100000, 10)
400+
for b.Loop() {
401+
var buf bytes.Buffer
402+
w := csv.NewWriter(&buf)
403+
_ = w.WriteAll(records)
404+
}
405+
}
406+
407+
func BenchmarkWriteAll_Simple_100K_SIMD(b *testing.B) {
408+
records := generateSimpleRecords(100000, 10)
409+
for b.Loop() {
410+
var buf bytes.Buffer
411+
w := NewWriter(&buf)
412+
_ = w.WriteAll(records)
413+
}
414+
}
415+
416+
// =============================================================================
417+
// WriteAll Benchmarks - Quoted CSV
418+
// =============================================================================
419+
420+
func BenchmarkWriteAll_Quoted_1K_Stdlib(b *testing.B) {
421+
records := generateQuotedRecords(1000, 10)
422+
for b.Loop() {
423+
var buf bytes.Buffer
424+
w := csv.NewWriter(&buf)
425+
_ = w.WriteAll(records)
426+
}
427+
}
428+
429+
func BenchmarkWriteAll_Quoted_1K_SIMD(b *testing.B) {
430+
records := generateQuotedRecords(1000, 10)
431+
for b.Loop() {
432+
var buf bytes.Buffer
433+
w := NewWriter(&buf)
434+
_ = w.WriteAll(records)
435+
}
436+
}
437+
438+
func BenchmarkWriteAll_Quoted_10K_Stdlib(b *testing.B) {
439+
records := generateQuotedRecords(10000, 10)
440+
for b.Loop() {
441+
var buf bytes.Buffer
442+
w := csv.NewWriter(&buf)
443+
_ = w.WriteAll(records)
444+
}
445+
}
446+
447+
func BenchmarkWriteAll_Quoted_10K_SIMD(b *testing.B) {
448+
records := generateQuotedRecords(10000, 10)
449+
for b.Loop() {
450+
var buf bytes.Buffer
451+
w := NewWriter(&buf)
452+
_ = w.WriteAll(records)
453+
}
454+
}
455+
456+
// =============================================================================
457+
// WriteAll Benchmarks - Mixed CSV
458+
// =============================================================================
459+
460+
func BenchmarkWriteAll_Mixed_1K_Stdlib(b *testing.B) {
461+
records := generateMixedRecords(1000, 10)
462+
for b.Loop() {
463+
var buf bytes.Buffer
464+
w := csv.NewWriter(&buf)
465+
_ = w.WriteAll(records)
466+
}
467+
}
468+
469+
func BenchmarkWriteAll_Mixed_1K_SIMD(b *testing.B) {
470+
records := generateMixedRecords(1000, 10)
471+
for b.Loop() {
472+
var buf bytes.Buffer
473+
w := NewWriter(&buf)
474+
_ = w.WriteAll(records)
475+
}
476+
}
477+
478+
func BenchmarkWriteAll_Mixed_10K_Stdlib(b *testing.B) {
479+
records := generateMixedRecords(10000, 10)
480+
for b.Loop() {
481+
var buf bytes.Buffer
482+
w := csv.NewWriter(&buf)
483+
_ = w.WriteAll(records)
484+
}
485+
}
486+
487+
func BenchmarkWriteAll_Mixed_10K_SIMD(b *testing.B) {
488+
records := generateMixedRecords(10000, 10)
489+
for b.Loop() {
490+
var buf bytes.Buffer
491+
w := NewWriter(&buf)
492+
_ = w.WriteAll(records)
493+
}
494+
}
495+
496+
// =============================================================================
497+
// WriteAll Benchmarks - Escaped Quotes CSV
498+
// =============================================================================
499+
500+
func BenchmarkWriteAll_EscapedQuotes_1K_Stdlib(b *testing.B) {
501+
records := generateEscapedQuotesRecords(1000, 10)
502+
for b.Loop() {
503+
var buf bytes.Buffer
504+
w := csv.NewWriter(&buf)
505+
_ = w.WriteAll(records)
506+
}
507+
}
508+
509+
func BenchmarkWriteAll_EscapedQuotes_1K_SIMD(b *testing.B) {
510+
records := generateEscapedQuotesRecords(1000, 10)
511+
for b.Loop() {
512+
var buf bytes.Buffer
513+
w := NewWriter(&buf)
514+
_ = w.WriteAll(records)
515+
}
516+
}
517+
518+
func BenchmarkWriteAll_EscapedQuotes_10K_Stdlib(b *testing.B) {
519+
records := generateEscapedQuotesRecords(10000, 10)
520+
for b.Loop() {
521+
var buf bytes.Buffer
522+
w := csv.NewWriter(&buf)
523+
_ = w.WriteAll(records)
524+
}
525+
}
526+
527+
func BenchmarkWriteAll_EscapedQuotes_10K_SIMD(b *testing.B) {
528+
records := generateEscapedQuotesRecords(10000, 10)
529+
for b.Loop() {
530+
var buf bytes.Buffer
531+
w := NewWriter(&buf)
532+
_ = w.WriteAll(records)
533+
}
534+
}
535+
536+
// =============================================================================
537+
// Record-by-Record Write Benchmarks
538+
// =============================================================================
539+
540+
func BenchmarkWrite_RecordByRecord_10K_Stdlib(b *testing.B) {
541+
records := generateSimpleRecords(10000, 10)
542+
for b.Loop() {
543+
var buf bytes.Buffer
544+
w := csv.NewWriter(&buf)
545+
for _, record := range records {
546+
_ = w.Write(record)
547+
}
548+
w.Flush()
549+
}
550+
}
551+
552+
func BenchmarkWrite_RecordByRecord_10K_SIMD(b *testing.B) {
553+
records := generateSimpleRecords(10000, 10)
554+
for b.Loop() {
555+
var buf bytes.Buffer
556+
w := NewWriter(&buf)
557+
for _, record := range records {
558+
_ = w.Write(record)
559+
}
560+
_ = w.Flush()
561+
}
562+
}
563+
358564
// =============================================================================
359565
// scanBuffer Benchmarks
360566
// =============================================================================

test_helpers_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,63 @@ func generateEscapedQuotesCSV(numRows, numCols int) []byte {
202202
}
203203
return buf.Bytes()
204204
}
205+
206+
// =============================================================================
207+
// Writer Benchmark Record Generators
208+
// =============================================================================
209+
210+
// generateSimpleRecords generates records with simple unquoted fields.
211+
func generateSimpleRecords(numRows, numCols int) [][]string {
212+
records := make([][]string, numRows)
213+
for i := range records {
214+
record := make([]string, numCols)
215+
for j := range record {
216+
record[j] = "field"
217+
}
218+
records[i] = record
219+
}
220+
return records
221+
}
222+
223+
// generateQuotedRecords generates records with fields containing commas (requires quoting).
224+
func generateQuotedRecords(numRows, numCols int) [][]string {
225+
records := make([][]string, numRows)
226+
for i := range records {
227+
record := make([]string, numCols)
228+
for j := range record {
229+
record[j] = "field,with,commas"
230+
}
231+
records[i] = record
232+
}
233+
return records
234+
}
235+
236+
// generateMixedRecords generates records with mixed simple/quoted fields.
237+
func generateMixedRecords(numRows, numCols int) [][]string {
238+
records := make([][]string, numRows)
239+
for i := range records {
240+
record := make([]string, numCols)
241+
for j := range record {
242+
if j%2 == 0 {
243+
record[j] = "simple"
244+
} else {
245+
record[j] = "quoted,field"
246+
}
247+
}
248+
records[i] = record
249+
}
250+
return records
251+
}
252+
253+
// generateEscapedQuotesRecords generates records with fields containing quotes (requires escaping).
254+
func generateEscapedQuotesRecords(numRows, numCols int) [][]string {
255+
records := make([][]string, numRows)
256+
for i := range records {
257+
record := make([]string, numCols)
258+
for j := range record {
259+
record[j] = `he said "hello" to me`
260+
}
261+
records[i] = record
262+
}
263+
return records
264+
}

0 commit comments

Comments
 (0)