diff --git a/labs31/README.md b/labs31/README.md index e360ab1..effc3c7 100644 --- a/labs31/README.md +++ b/labs31/README.md @@ -2,22 +2,29 @@ 最直接的办法就是循环计算,因为2的20次幂就达到1M的大小了,这么大的内存块其实没有缓存的必要了,所以循环最多也就20次。 -但是我很蛋疼了测试了sort包的Search函数,switch循环展开、if循环展开和人肉折半查找。 +但是我很蛋疼了测试了sort包的Search函数,switch循环展开、if循环展开、人肉折半查找、浮点数取指数。 我电脑上测试结果如下: -``` + +go version 1.7.3 + $ go test -bench="." +PASS` +Benchmark_Normal-8 100000000 22.8 ns/op +Benchmark_Search-8 100000000 21.5 ns/op +Benchmark_Search2-8 200000000 6.62 ns/op +Benchmark_Switch-8 200000000 7.54 ns/op +Benchmark_IF1-8 300000000 4.33 ns/op +Benchmark_IF2-8 500000000 2.71 ns/op +Benchmark_IF3-8 2000000000 1.09 ns/op +Benchmark_IF4-8 200000000 7.12 ns/op +Benchmark_IF5-8 2000000000 0.61 ns/op PASS -Benchmark_Normal-4 50000000 25.6 ns/op -Benchmark_Search-4 100000000 21.7 ns/op -Benchmark_Switch-4 100000000 12.5 ns/op -Benchmark_IF1-4 200000000 9.14 ns/op -Benchmark_IF2-4 300000000 3.89 ns/op -Benchmark_IF3-4 1000000000 2.37 ns/op -ok github.com/idada/go-labs/labs31 11.822s -``` +ok command-line-arguments 18.027s + 呵呵,蛋好疼。 -补充:最后一个IF3测试是由群里的v1zze同学提供的算法,果然牛逼。 \ No newline at end of file +补充:最后一个IF3测试是由群里的v1zze同学提供的算法,果然牛逼。 +IF4 和 IF5 使用浮点数取指数计 diff --git a/labs31/labs31_test.go b/labs31/labs31_test.go index 977e402..90194cd 100644 --- a/labs31/labs31_test.go +++ b/labs31/labs31_test.go @@ -1,6 +1,7 @@ package labs31 import ( + "math" "math/rand" "sort" "testing" @@ -23,11 +24,14 @@ func Test_All(t *testing.T) { d := IF2(n) e := Search(n) f := IF3(n) + g := IF4(n) + h := IF5(n) + i := SearchInt(n) if f > 21 { f = 21 } - if a != b || b != c || c != d || d != e || e != f { - t.Log(n, a, b, c, d, e, f) + if a != b || b != c || c != d || d != e || e != f || f != g || g != h || h != i { + t.Log(n, a, b, c, d, e, f, g, h, i) t.Fail() } } @@ -45,6 +49,12 @@ func Benchmark_Search(b *testing.B) { } } +func Benchmark_Search2(b *testing.B) { + for i := 0; i < b.N; i++ { + SearchInt(benchx) + } +} + func Benchmark_Switch(b *testing.B) { for i := 0; i < b.N; i++ { Switch(benchx) @@ -69,6 +79,18 @@ func Benchmark_IF3(b *testing.B) { } } +func Benchmark_IF4(b *testing.B) { + for i := 0; i < b.N; i++ { + IF4(benchx) + } +} + +func Benchmark_IF5(b *testing.B) { + for i := 0; i < b.N; i++ { + IF5(benchx) + } +} + func Normal(n int) uint { var i = uint(0) for ; n > (1< answer is i. + return uint(i) +} + func Switch(n int) uint { switch { case n == 1: @@ -299,3 +340,23 @@ func IF3(n int) uint { } return c } + +func IF4(n int) uint { + n-- + ix := math.Ilogb(float64(n)) + if ix > 20 { + ix = 20 + } + ix++ + return uint(ix) +} + +func IF5(n int) uint { + n-- + ix := (math.Float32bits(float32(n))>>23)&0xff - 127 + if ix > 20 { + ix = 20 + } + ix++ + return uint(ix) +}