@@ -146,6 +146,8 @@ func Decompress(dst []float64, data []byte) []float64 {
146146
147147 // Use lookup table for power of 10.
148148 factor := powersOf10 [metadata .Exponent + 10 ]
149+ // Pre-compute inverse to use multiplication instead of division
150+ invFactor := 1.0 / factor
149151
150152 // Combined loop: add minValue and convert to float64 in one pass
151153 // This reduces memory traffic and allows better optimization
@@ -155,13 +157,13 @@ func Decompress(dst []float64, data []byte) []float64 {
155157 _ = ints [i + 3 ]
156158 _ = result [i + 3 ]
157159
158- result [i ] = float64 (ints [i ]+ minValue ) / factor
159- result [i + 1 ] = float64 (ints [i + 1 ]+ minValue ) / factor
160- result [i + 2 ] = float64 (ints [i + 2 ]+ minValue ) / factor
161- result [i + 3 ] = float64 (ints [i + 3 ]+ minValue ) / factor
160+ result [i ] = float64 (ints [i ]+ minValue ) * invFactor
161+ result [i + 1 ] = float64 (ints [i + 1 ]+ minValue ) * invFactor
162+ result [i + 2 ] = float64 (ints [i + 2 ]+ minValue ) * invFactor
163+ result [i + 3 ] = float64 (ints [i + 3 ]+ minValue ) * invFactor
162164 }
163165 for ; i < numValues ; i ++ {
164- result [i ] = float64 (ints [i ]+ minValue ) / factor
166+ result [i ] = float64 (ints [i ]+ minValue ) * invFactor
165167 }
166168
167169 return dst [:metadata .Count ]
@@ -185,6 +187,8 @@ func findBestExponent(data []float64) int {
185187 // Try different exponents
186188 for exp := MinExponent ; exp <= MaxExponent ; exp ++ {
187189 factor := powersOf10 [exp + 10 ]
190+ // Pre-compute inverse to match decompression exactly
191+ invFactor := 1.0 / factor
188192 maxBits := 0
189193 valid := true
190194
@@ -197,8 +201,8 @@ func findBestExponent(data []float64) int {
197201 rounded := math .Round (scaled )
198202 intValue := int64 (rounded )
199203
200- // Reconstruct and check if lossless
201- reconstructed := float64 (intValue ) / factor
204+ // Reconstruct and check if lossless using same method as decompression
205+ reconstructed := float64 (intValue ) * invFactor
202206 relativeError := math .Abs (original - reconstructed )
203207 if original != 0 {
204208 relativeError /= math .Abs (original )
@@ -263,8 +267,24 @@ func DecompressValues(result []float64, src []byte, metadata CompressionMetadata
263267 // Reverse frame-of-reference and convert back to float64 in one pass
264268 minValue := metadata .FrameOfRef
265269 factor := powersOf10 [metadata .Exponent + 10 ]
266- for i := range metadata .Count {
267- result [i ] = float64 (unpacked [i ]+ minValue ) / factor
270+ // Pre-compute inverse to use multiplication instead of division
271+ invFactor := 1.0 / factor
272+ numValues := metadata .Count
273+
274+ // Unroll loop for better performance
275+ i := int32 (0 )
276+ for ; i + 3 < numValues ; i += 4 {
277+ // Bounds check hint for the group of 4
278+ _ = unpacked [i + 3 ]
279+ _ = result [i + 3 ]
280+
281+ result [i ] = float64 (unpacked [i ]+ minValue ) * invFactor
282+ result [i + 1 ] = float64 (unpacked [i + 1 ]+ minValue ) * invFactor
283+ result [i + 2 ] = float64 (unpacked [i + 2 ]+ minValue ) * invFactor
284+ result [i + 3 ] = float64 (unpacked [i + 3 ]+ minValue ) * invFactor
285+ }
286+ for ; i < numValues ; i ++ {
287+ result [i ] = float64 (unpacked [i ]+ minValue ) * invFactor
268288 }
269289 }
270290}
0 commit comments