github.com/cockroachdb/apd/v3@v3.2.0/bench_test.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. See the License for the specific language governing 13 // permissions and limitations under the License. 14 15 package apd 16 17 import ( 18 "bytes" 19 "fmt" 20 "math/rand" 21 "testing" 22 ) 23 24 // runBenches benchmarks a given function on random decimals on combinations of 25 // three parameters: 26 // 27 // precision: desired output precision 28 // inScale: the scale of the input decimal: the absolute value will be between 29 // 10^inScale and 10^(inScale+1) 30 // inNumDigits: number of digits in the input decimal; if negative the number 31 // will be negative and the number of digits are the absolute value. 32 func runBenches( 33 b *testing.B, precision, inScale, inNumDigits []int, fn func(*testing.B, *Context, *Decimal), 34 ) { 35 for _, p := range precision { 36 ctx := BaseContext.WithPrecision(uint32(p)) 37 for _, s := range inScale { 38 for _, d := range inNumDigits { 39 numDigits := d 40 negative := false 41 if d < 0 { 42 numDigits = -d 43 negative = true 44 } 45 if numDigits > p { 46 // Skip cases where we have more digits than the desired precision. 47 continue 48 } 49 50 // Generate some random numbers with the given number of digits. 51 nums := make([]Decimal, 20) 52 for i := range nums { 53 var buf bytes.Buffer 54 if negative { 55 buf.WriteByte('-') 56 } 57 buf.WriteByte('1' + byte(rand.Intn(9))) 58 for j := 1; j < numDigits; j++ { 59 buf.WriteByte('0' + byte(rand.Intn(10))) 60 } 61 if _, _, err := nums[i].SetString(buf.String()); err != nil { 62 b.Fatal(err) 63 } 64 nums[i].Exponent = int32(s - numDigits) 65 } 66 b.Run( 67 fmt.Sprintf("P%d/S%d/D%d", p, s, d), 68 func(b *testing.B) { 69 for i := 0; i <= b.N; i++ { 70 fn(b, ctx, &nums[i%len(nums)]) 71 } 72 }, 73 ) 74 } 75 } 76 } 77 } 78 79 func BenchmarkExp(b *testing.B) { 80 precision := []int{5, 10, 100} 81 scale := []int{-4, -1, 2} 82 digits := []int{-100, -10, -2, 2, 10, 100} 83 runBenches( 84 b, precision, scale, digits, 85 func(b *testing.B, ctx *Context, x *Decimal) { 86 if _, err := ctx.Exp(&Decimal{}, x); err != nil { 87 b.Fatal(err) 88 } 89 }, 90 ) 91 } 92 93 func BenchmarkLn(b *testing.B) { 94 precision := []int{2, 10, 100} 95 scale := []int{-100, -10, -2, 2, 10, 100} 96 digits := []int{2, 10, 100} 97 runBenches( 98 b, precision, scale, digits, 99 func(b *testing.B, ctx *Context, x *Decimal) { 100 if _, err := ctx.Ln(&Decimal{}, x); err != nil { 101 b.Fatal(err) 102 } 103 }, 104 ) 105 } 106 107 func BenchmarkDecimalString(b *testing.B) { 108 rng := rand.New(rand.NewSource(461210934723948)) 109 corpus := func() []Decimal { 110 res := make([]Decimal, 8192) 111 for i := range res { 112 _, err := res[i].SetFloat64(rng.Float64()) 113 if err != nil { 114 b.Fatal(err) 115 } 116 } 117 return res 118 }() 119 b.ResetTimer() 120 b.ReportAllocs() 121 for i := 0; i < b.N; i++ { 122 _ = corpus[rng.Intn(len(corpus))].String() 123 } 124 }