From 84ef97b59c89b7d9fdc04a1a8a438cd3257bf521 Mon Sep 17 00:00:00 2001 From: Dave Cheney Date: Sat, 14 Apr 2012 21:34:08 +1000 Subject: [PATCH] strconv: make malloc tests more reliable Fixes #3495. I adapted fmt.TestCountMallocs to fix the existing tests. As the resulting tests did not appear to belong to either itoa or ftoa I moved them into their own file. R=bradfitz, fullung CC=golang-dev https://golang.org/cl/5985072 --- src/pkg/strconv/ftoa_test.go | 17 ----------- src/pkg/strconv/itoa_test.go | 30 ------------------- src/pkg/strconv/strconv_test.go | 51 +++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 src/pkg/strconv/strconv_test.go diff --git a/src/pkg/strconv/ftoa_test.go b/src/pkg/strconv/ftoa_test.go index 7d8617a854..f69e3624ed 100644 --- a/src/pkg/strconv/ftoa_test.go +++ b/src/pkg/strconv/ftoa_test.go @@ -173,23 +173,6 @@ func TestFtoaRandom(t *testing.T) { } } -func TestAppendFloatDoesntAllocate(t *testing.T) { - n := numAllocations(func() { - var buf [64]byte - AppendFloat(buf[:0], 1.23, 'g', 5, 64) - }) - want := 1 // TODO(bradfitz): this might be 0, once escape analysis is better - if n != want { - t.Errorf("with local buffer, did %d allocations, want %d", n, want) - } - n = numAllocations(func() { - AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64) - }) - if n != 0 { - t.Errorf("with reused buffer, did %d allocations, want 0", n) - } -} - func BenchmarkFormatFloatDecimal(b *testing.B) { for i := 0; i < b.N; i++ { FormatFloat(33909, 'g', -1, 64) diff --git a/src/pkg/strconv/itoa_test.go b/src/pkg/strconv/itoa_test.go index 1486ee214d..e0213ae9af 100644 --- a/src/pkg/strconv/itoa_test.go +++ b/src/pkg/strconv/itoa_test.go @@ -5,7 +5,6 @@ package strconv_test import ( - "runtime" . "strconv" "testing" ) @@ -126,35 +125,6 @@ func TestUitoa(t *testing.T) { } } -func numAllocations(f func()) int { - runtime.GC() - memstats := new(runtime.MemStats) - runtime.ReadMemStats(memstats) - n0 := memstats.Mallocs - f() - runtime.ReadMemStats(memstats) - return int(memstats.Mallocs - n0) -} - -var globalBuf [64]byte - -func TestAppendUintDoesntAllocate(t *testing.T) { - n := numAllocations(func() { - var buf [64]byte - AppendInt(buf[:0], 123, 10) - }) - want := 1 // TODO(bradfitz): this might be 0, once escape analysis is better - if n != want { - t.Errorf("with local buffer, did %d allocations, want %d", n, want) - } - n = numAllocations(func() { - AppendInt(globalBuf[:0], 123, 10) - }) - if n != 0 { - t.Errorf("with reused buffer, did %d allocations, want 0", n) - } -} - func BenchmarkFormatInt(b *testing.B) { for i := 0; i < b.N; i++ { for _, test := range itob64tests { diff --git a/src/pkg/strconv/strconv_test.go b/src/pkg/strconv/strconv_test.go new file mode 100644 index 0000000000..f6707ba87b --- /dev/null +++ b/src/pkg/strconv/strconv_test.go @@ -0,0 +1,51 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package strconv_test + +import ( + "runtime" + . "strconv" + "testing" +) + +var ( + globalBuf [64]byte + + mallocTest = []struct { + count int + desc string + fn func() + }{ + // TODO(bradfitz): this might be 0, once escape analysis is better + {1, `AppendInt(localBuf[:0], 123, 10)`, func() { + var localBuf [64]byte + AppendInt(localBuf[:0], 123, 10) + }}, + {0, `AppendInt(globalBuf[:0], 123, 10)`, func() { AppendInt(globalBuf[:0], 123, 10) }}, + // TODO(bradfitz): this might be 0, once escape analysis is better + {1, `AppendFloat(localBuf[:0], 1.23, 'g', 5, 64)`, func() { + var localBuf [64]byte + AppendFloat(localBuf[:0], 1.23, 'g', 5, 64) + }}, + {0, `AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64)`, func() { AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64) }}, + } +) + +func TestCountMallocs(t *testing.T) { + for _, mt := range mallocTest { + const N = 100 + memstats := new(runtime.MemStats) + runtime.ReadMemStats(memstats) + mallocs := 0 - memstats.Mallocs + for i := 0; i < N; i++ { + mt.fn() + } + runtime.ReadMemStats(memstats) + mallocs += memstats.Mallocs + if mallocs/N > uint64(mt.count) { + t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N) + } + } +} -- 2.48.1