resource: optimize scale function

The original scale function takes around 800ns/op with more
than 10 allocations. It significantly slow down scheduler
and other components that heavily relys on resource pkg.
For more information see #18126.

This pull request tries to optimize scale function. It takes
two approach:

1. when the value is small, only use normal math ops.
2. when the value is large, use math.Big with buffer pool.

The final result is:

BenchmarkScaledValueSmall-4	20000000	        66.9 ns/op	       0 B/op	       0 allocs/op
BenchmarkScaledValueLarge-4	 2000000	       711 ns/op	      48 B/op	       1 allocs/op

I also run the scheduler benchmark again. It doubles the throughput of
scheduler for 1000 nodes case.
This commit is contained in:
Xiang Li
2015-12-03 13:11:50 -08:00
parent b7d8221296
commit cf82d6b004
3 changed files with 182 additions and 4 deletions

View File

@@ -377,8 +377,7 @@ func (q *Quantity) Value() int64 {
if q.Amount == nil {
return 0
}
tmp := &inf.Dec{}
return tmp.Round(q.Amount, 0, inf.RoundUp).UnscaledBig().Int64()
return scaledValue(q.Amount.UnscaledBig(), int(q.Amount.Scale()), 0)
}
// MilliValue returns the value of q * 1000; this could overflow an int64;
@@ -387,8 +386,7 @@ func (q *Quantity) MilliValue() int64 {
if q.Amount == nil {
return 0
}
tmp := &inf.Dec{}
return tmp.Round(tmp.Mul(q.Amount, decThousand), 0, inf.RoundUp).UnscaledBig().Int64()
return scaledValue(q.Amount.UnscaledBig(), int(q.Amount.Scale()), 3)
}
// Set sets q's value to be value.