Commit ac73c1b1 authored by Sylvain Henry's avatar Sylvain Henry Committed by Marge Bot

Faster exactLog2

Make `exactLog2` faster (use `countLeadingZeros` and Int32 bit-ops).

On my Core i7-9700k Criterion reports ~50% speedup (from 16 to 8ns).
parent 47e16237
...@@ -1123,22 +1123,16 @@ toArgs str ...@@ -1123,22 +1123,16 @@ toArgs str
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Integers -- Integers
-- This algorithm for determining the $\log_2$ of exact powers of 2 comes -- | Determine the $\log_2$ of exact powers of 2
-- from GCC. It requires bit manipulation primitives, and we use GHC
-- extensions. Tough.
exactLog2 :: Integer -> Maybe Integer exactLog2 :: Integer -> Maybe Integer
exactLog2 x exactLog2 x
= if (x <= 0 || x >= 2147483648) then | x <= 0 = Nothing
Nothing | x > fromIntegral (maxBound :: Int32) = Nothing
else | x' .&. (-x') /= x' = Nothing
if (x .&. (-x)) /= x then | otherwise = Just (fromIntegral c)
Nothing where
else x' = fromIntegral x :: Int32
Just (pow2 x) c = countTrailingZeros x'
where
pow2 x | x == 1 = 0
| otherwise = 1 + pow2 (x `shiftR` 1)
{- {-
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment