Files
bl/common/utils/sqrt_test.go
昔念 cd7583ba05 test(utils): 添加事件驱动模型测试
- 在 sqrt_test.go 中添加了 fastSqr1 测试函数,用于测试事件驱动模型
- 新增了 Event 和 Uint32AsyncEvent 类型用于测试
- 更新了 go.work、go.mod 和
2025-08-05 16:10:18 +08:00

169 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package utils
import (
"fmt"
"math"
"testing"
"github.com/badu/bus"
)
func Test_fastSqrt(t *testing.T) {
// 测试用例
testCases := []float64{2, 4, 10, 16, 25, 100, 1000, 0.5, 0.01, 1e-20}
fmt.Println("测试卡马克快速平方根算法与标准库的对比:")
fmt.Println("数值\t快速算法结果\t标准库结果\t绝对误差")
fmt.Println("--------------------------------------------------------------")
for _, x := range testCases {
fastResult := fastSqrt(x)
stdResult := math.Sqrt(x)
error := math.Abs(fastResult - stdResult)
fmt.Printf("%.10g\t%.10g\t\t%.10g\t\t%.2e\n",
x, fastResult, stdResult, error)
}
// 测试整数版本
fmt.Println("\n测试整数快速平方根算法")
fmt.Println("数值\t快速算法结果\t标准库转换结果")
fmt.Println("--------------------------------------")
for _, x := range []int{2, 4, 10, 16, 25, 100, 1000} {
fastResult := fastSqrtInt(x)
stdResult := int(math.Sqrt(float64(x)))
fmt.Printf("%d\t%d\t\t%d\n", x, fastResult, stdResult)
}
}
func BenchmarkMathSqrt(b *testing.B) {
testValues := []float64{2, 4, 10, 16, 25, 100, 1000, 0.5, 0.01, 1e-20}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, x := range testValues {
_ = math.Sqrt(x)
}
}
}
func BenchmarkFastSqrt(b *testing.B) {
testValues := []float64{2, 4, 10, 16, 25, 100, 1000, 0.5, 0.01, 1e-20}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, x := range testValues {
_ = fastSqrt(x)
}
}
}
func BenchmarkFastSqrtCarmack(b *testing.B) {
testValues := []float64{2, 4, 10, 16, 25, 100, 1000, 0.5, 0.01, 1e-20}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, x := range testValues {
_ = fastSqrtCarmack(x)
}
}
}
func BenchmarkMathSqrtInt(b *testing.B) {
testValues := []int{2, 4, 10, 16, 25, 100, 1000, 10000, 100000}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, x := range testValues {
_ = int(math.Sqrt(float64(x)))
}
}
}
func BenchmarkFastSqrtInt(b *testing.B) {
testValues := []int{2, 4, 10, 16, 25, 100, 1000, 10000, 100000}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, x := range testValues {
_ = fastSqrtInt(x)
}
}
}
func Test_fastSqr1(b *testing.T) {
// scenario : we have a large number of subscribers.
// we publish an event and while doing that,
// we register another one on a different goroutine
topic := bus.NewTopic[*Uint32AsyncEvent]()
for i := 0; i < 4096; i++ {
topic.Sub(func(v *Uint32AsyncEvent) {
print(v.u)
})
}
topic.Pub(&Uint32AsyncEvent{u: 1})
// finishPubWait := make(chan struct{})
// finishSubWait := make(chan struct{})
// start := make(chan struct{})
// go func() {
// <-start
// topic.PubAsync(&Uint32AsyncEvent{u: 1})
// defer close(finishPubWait)
// }()
// newSubCalled := false
// go func() {
// <-start
// topic.Sub(func(v *Uint32AsyncEvent) {
// newSubCalled = true
// })
// close(finishSubWait)
// }()
// close(start) // start both goroutines
// <-finishPubWait // wait for pub to finish
// <-finishSubWait // wait for sub to finish
// if newSubCalled {
// print("new subscriber called")
// }
}
// Various event types
const EventA = 0x01
type Uint32AsyncEvent struct {
u uint32
}
// Event type for testing purposes
type Event struct {
Data string
type1 uint32
}
// Type returns the event type
func (ev Event) Type() uint32 {
return ev.type1
}
// newEventA creates a new instance of an event
func newEventA(data string) Event {
return Event{Data: data, type1: EventA}
}
// Various event types
const EventB1 = 0x02
func newEventB(data string) Event {
return Event{Data: data, type1: EventB1}
}