[GHC] #10944: powModInteger slower than computing pow and mod separately

GHC ghc-devs at haskell.org
Thu Oct 8 13:42:31 UTC 2015


#10944: powModInteger slower than computing pow and mod separately
-------------------------------------+-------------------------------------
        Reporter:  iago              |                Owner:
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Core Libraries    |              Version:  7.8.3
      Resolution:                    |             Keywords:  integer-gmp
Operating System:  Linux             |         Architecture:  x86_64
 Type of failure:  Runtime           |  (amd64)
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
-------------------------------------+-------------------------------------

Comment (by bgamari):

 I'm afraid I am unable to reproduce this. Could you provide a concrete
 test case which quantitatively demonstrates the difference?

 For the record, I my attempt was,

 {{{#!hs
 import GHC.Integer.GMP.Internals ( powModInteger )

 main = defaultMain
   [ bench "test1" $ whnf (\(a,b,c) -> test1 a b c) (5,76,2)
   , bench "powModInteger" $ whnf (\(a,b,c) -> test2 a b c) (5,76,2)

   , bench "list test1" $ whnf (sum . map (\(a,b,c) -> test1 a b c)) xs
   , bench "list test2" $ whnf (sum . map (\(a,b,c) -> test2 a b c)) xs
   ]

 xs :: [(Integer, Integer, Int)]
 xs = do
   a <- [1..5]
   b <- [50..60]
   c <- [2..4]
   return (a,b,c)

 test1, test2 :: Integer -> Integer -> Int -> Integer
 test1 a b c = (a ^ b) `mod` (2^c)
 test2 a b c = powModInteger a b (2^c)
 }}}

 which resulted in,
 {{{
 $ ghc -V
 The Glorious Glasgow Haskell Compilation System, version 7.10.2
 $ ghc -O Hi.hs
 [1 of 1] Compiling Main             ( Hi.hs, Hi.o )
 Linking Hi ...
 $ ./Hi
 benchmarking test1
 time                 567.7 ns   (562.9 ns .. 571.6 ns)
                      1.000 R²   (0.999 R² .. 1.000 R²)
 mean                 566.7 ns   (562.5 ns .. 571.9 ns)
 std dev              15.85 ns   (12.92 ns .. 19.35 ns)
 variance introduced by outliers: 39% (moderately inflated)

 benchmarking powModInteger
 time                 440.7 ns   (438.4 ns .. 443.3 ns)
                      1.000 R²   (1.000 R² .. 1.000 R²)
 mean                 443.6 ns   (440.8 ns .. 446.9 ns)
 std dev              9.862 ns   (8.180 ns .. 12.19 ns)
 variance introduced by outliers: 29% (moderately inflated)

 benchmarking list test1
 time                 97.44 μs   (96.68 μs .. 98.31 μs)
                      0.999 R²   (0.999 R² .. 0.999 R²)
 mean                 97.59 μs   (96.58 μs .. 98.57 μs)
 std dev              3.431 μs   (2.833 μs .. 4.300 μs)
 variance introduced by outliers: 35% (moderately inflated)

 benchmarking list test2
 time                 76.43 μs   (75.85 μs .. 76.92 μs)
                      0.999 R²   (0.999 R² .. 1.000 R²)
 mean                 76.55 μs   (76.08 μs .. 77.11 μs)
 std dev              1.698 μs   (1.412 μs .. 2.126 μs)
 variance introduced by outliers: 18% (moderately inflated)
 }}}

 This is the sort of modest speed-up that I would have expected from
 `powModInteger`. I found similar results with 7.8.4.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10944#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list