quot
vòng về phía zero, div
vòng về phía vô cực âm:
div (-3) 2 == (-2)
quot (-3) 2 == (-1)
Đối với các overhead của div
, quot
có một tương ứng primitive GHC operation, trong khi div
không some extra work:
quotRemInt :: Int -> Int -> (Int, Int)
(I# x) `quotRemInt` (I# y) = case x `quotRemInt#` y of
(# q, r #) ->
(I# q, I# r)
divModInt# :: Int# -> Int# -> (# Int#, Int# #)
x# `divModInt#` y#
| (x# ># 0#) && (y# <# 0#) = case (x# -# 1#) `quotRemInt#` y# of
(# q, r #) -> (# q -# 1#, r +# y# +# 1# #)
| (x# <# 0#) && (y# ># 0#) = case (x# +# 1#) `quotRemInt#` y# of
(# q, r #) -> (# q -# 1#, r +# y# -# 1# #)
| otherwise = x# `quotRemInt#` y#
Trong cuối cùng của họ biểu mẫu, cả hai hàm đều có một số error handling checks on them:
a `quot` b
| b == 0 = divZeroError
| b == (-1) && a == minBound = overflowError -- Note [Order of tests]
-- in GHC.Int
| otherwise = a `quotInt` b
a `div` b
| b == 0 = divZeroError
| b == (-1) && a == minBound = overflowError -- Note [Order of tests]
-- in GHC.Int
| otherwise = a `divInt` b
Tôi cũng đã làm một chút rất nhỏ của microbenchmarking, nhưng nó nên được thực hiện với một lượng muối khổng lồ, bởi vì GHC và LLVM tối ưu hóa mã số chặt chẽ đi như không có ngày mai. Tôi đã cố ngăn chặn chúng và kết quả dường như thực tế: 14,67 ms cho div
và 13,37 ms cho quot
. Ngoài ra, nó là GHC 7.8.2 với -O2 và -fllvm. Dưới đây là các mã:
{-# LANGUAGE BangPatterns #-}
import Criterion.Main
import System.Random
benchOp :: (Int -> Int) -> Int ->()
benchOp f = go 0 0 where
go !i !acc !limit | i < limit = go (i + 1) (f i) limit
| otherwise =()
main = do
limit1 <- randomRIO (1000000, 1000000 :: Int)
limit2 <- randomRIO (1000000, 1000000 :: Int)
n <- randomRIO (100, 100 :: Int)
defaultMain [
bench "div" $ whnf (benchOp (`div` n)) limit1,
bench "quot" $ whnf (benchOp (`quot` n)) limit2]
Tôi đã thêm một chút nhỏ bé của điểm chuẩn quá, FYI. –
@ AndrásKovács Cảm ơn bạn đã trả lời tuyệt vời! : D – ThreeFx
Khi @augustss đề cập đến câu trả lời cho câu hỏi mà bạn đã liên kết, lý do * cơ bản cho sự khác biệt tốc độ là 'quot' là những gì thường được thực hiện trực tiếp như một lệnh trong CPU hiện đại. Như vậy, như đã đề cập dưới đây, đó là những gì GHC chọn làm hoạt động nguyên thủy của nó. –