设计思路
- 高精度处理:使用
math/big
包中的 Float
类型来处理高精度浮点数,以避免普通 float32
或 float64
的舍入误差。
- 高并发优化:
- 采用缓存机制减少重复计算,例如使用
sync.Map
来缓存一些常用计算结果。
- 合理使用
goroutine
和 channel
来实现并发计算,提高整体性能。在并发操作时,对共享资源(如缓存)使用 sync.Mutex
进行保护。
关键数据结构
- Money:封装
math/big.Float
,方便对金额进行操作。
type Money struct {
amount *big.Float
}
- Cache:用于缓存计算结果。
type Cache struct {
sync.Map
}
函数实现
- 初始化
Money
func NewMoney(value string) (*Money, error) {
amount, ok := new(big.Float).SetString(value)
if!ok {
return nil, fmt.Errorf("invalid money value: %s", value)
}
return &Money{amount: amount}, nil
}
- 加法操作
func (m *Money) Add(other *Money) *Money {
result := new(big.Float).Add(m.amount, other.amount)
return &Money{amount: result}
}
- 减法操作
func (m *Money) Sub(other *Money) *Money {
result := new(big.Float).Sub(m.amount, other.amount)
return &Money{amount: result}
}
- 乘法操作
func (m *Money) Mul(other *Money) *Money {
result := new(big.Float).Mul(m.amount, other.amount)
return &Money{amount: result}
}
- 除法操作
func (m *Money) Div(other *Money) (*Money, error) {
if other.amount.Cmp(big.NewFloat(0)) == 0 {
return nil, fmt.Errorf("division by zero")
}
result := new(big.Float).Quo(m.amount, other.amount)
return &Money{amount: result}, nil
}
- 缓存操作
func (c *Cache) Get(key string) (*Money, bool) {
value, ok := c.Map.Load(key)
if ok {
return value.(*Money), true
}
return nil, false
}
func (c *Cache) Set(key string, value *Money) {
c.Map.Store(key, value)
}
- 并发计算示例
func concurrentCalculation(m1, m2 *Money, cache *Cache, op string) *Money {
var result *Money
key := fmt.Sprintf("%s_%s_%s", m1.amount.String(), m2.amount.String(), op)
if cached, ok := cache.Get(key); ok {
return cached
}
var ch = make(chan *Money)
go func() {
switch op {
case "add":
result = m1.Add(m2)
case "sub":
result = m1.Sub(m2)
case "mul":
result = m1.Mul(m2)
case "div":
var err error
result, err = m1.Div(m2)
if err != nil {
close(ch)
return
}
}
ch <- result
}()
if result = <-ch; result != nil {
cache.Set(key, result)
}
return result
}