mirror of
https://github.com/golang/go
synced 2024-10-14 11:53:56 +00:00
test: fix flaky NaN-key map complexity test
Don't measure wall time in map.go. Keep it portable and only test NaN, but not time. Move time tests to mapnan.go and only measure user CPU time, not wall time. It builds on Darwin and Linux, the primary platforms where people hack on the runtime & in particular maps. The runtime is shared, though, so we don't need it to run on all of the platforms. Fixes flaky build failures like: http://build.golang.org/log/ba67eceefdeaa1142cb6c990a62fa3ffd8fd73f8 R=golang-dev, r CC=golang-dev https://golang.org/cl/8479043
This commit is contained in:
parent
4235fa8f2a
commit
5e21cb7865
39
test/map.go
39
test/map.go
|
@ -5,6 +5,7 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Test maps, almost exhaustively.
|
||||
// NaN complexity test is in mapnan.go.
|
||||
|
||||
package main
|
||||
|
||||
|
@ -12,7 +13,6 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const count = 100
|
||||
|
@ -659,9 +659,7 @@ func testfloat() {
|
|||
}
|
||||
|
||||
func testnan() {
|
||||
// Test that NaNs in maps don't go quadratic.
|
||||
t := func(n int) time.Duration {
|
||||
t0 := time.Now()
|
||||
n := 500
|
||||
m := map[float64]int{}
|
||||
nan := math.NaN()
|
||||
for i := 0; i < n; i++ {
|
||||
|
@ -670,28 +668,17 @@ func testnan() {
|
|||
if len(m) != n {
|
||||
panic("wrong size map after nan insertion")
|
||||
}
|
||||
return time.Since(t0)
|
||||
iters := 0
|
||||
for k, v := range m {
|
||||
iters++
|
||||
if !math.IsNaN(k) {
|
||||
panic("not NaN")
|
||||
}
|
||||
|
||||
// Depending on the machine and OS, this test might be too fast
|
||||
// to measure with accurate enough granularity. On failure,
|
||||
// make it run longer, hoping that the timing granularity
|
||||
// is eventually sufficient.
|
||||
|
||||
n := 30000 // 0.02 seconds on a MacBook Air
|
||||
fails := 0
|
||||
for {
|
||||
t1 := t(n)
|
||||
t2 := t(2 * n)
|
||||
// should be 2x (linear); allow up to 3x
|
||||
if t2 < 3*t1 {
|
||||
return
|
||||
}
|
||||
fails++
|
||||
if fails == 4 {
|
||||
panic(fmt.Sprintf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2))
|
||||
return
|
||||
}
|
||||
n *= 2
|
||||
if v != 1 {
|
||||
panic("wrong value")
|
||||
}
|
||||
}
|
||||
if iters != n {
|
||||
panic("wrong number of nan range iters")
|
||||
}
|
||||
}
|
||||
|
|
64
test/mapnan.go
Normal file
64
test/mapnan.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
// +build darwin,linux
|
||||
// run
|
||||
|
||||
// Copyright 2013 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.
|
||||
|
||||
// Test that NaNs in maps don't go quadratic.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
// Test that NaNs in maps don't go quadratic.
|
||||
t := func(n int) time.Duration {
|
||||
var u0 syscall.Rusage
|
||||
if err := syscall.Getrusage(0, &u0); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := map[float64]int{}
|
||||
nan := math.NaN()
|
||||
for i := 0; i < n; i++ {
|
||||
m[nan] = 1
|
||||
}
|
||||
if len(m) != n {
|
||||
panic("wrong size map after nan insertion")
|
||||
}
|
||||
var u1 syscall.Rusage
|
||||
if err := syscall.Getrusage(0, &u1); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return time.Duration(u1.Utime.Nano() - u0.Utime.Nano())
|
||||
}
|
||||
|
||||
// Depending on the machine and OS, this test might be too fast
|
||||
// to measure with accurate enough granularity. On failure,
|
||||
// make it run longer, hoping that the timing granularity
|
||||
// is eventually sufficient.
|
||||
|
||||
n := 30000 // ~8ms user time on a Mid 2011 MacBook Air (1.8 GHz Core i7)
|
||||
fails := 0
|
||||
for {
|
||||
t1 := t(n)
|
||||
t2 := t(2 * n)
|
||||
// should be 2x (linear); allow up to 3x
|
||||
if t2 < 3*t1 {
|
||||
return
|
||||
}
|
||||
fails++
|
||||
if fails == 6 {
|
||||
panic(fmt.Sprintf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2))
|
||||
}
|
||||
if fails < 4 {
|
||||
n *= 2
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue