[Agda] Nat arithmetic performance
Sergei Meshveliani
mechvel at botik.ru
Sat Sep 24 12:52:22 CEST 2016
People,
Please, find attached a certain test for performance of arithmetic in
Agda, as compared to ghc-7.10.2.
Shortly saying, it is
sum [x*x - y*y | x, y <- [n .. 0]],
n = 1000, ..., 6000, ...
The Hasell program is also there.
{-
--------------------------------------------------------------------
Timing for Agda of September 16, 2016, ghc-7.10.2, 3 GHz computer
n | s (control) | time [sec]
| | Agda ghc-7.10.2 -O
--------------------------------------------------
1000 | 166499833500 | 0.3 | 0.04
2000 | 2665332667000 | 1.3 | 0.2
3000 | 13495498500500 | 3.0 | 0.4
4000 | 42655997334000 | 5.1 | 0.8
5000 | 104145829167500 | 8.0 | 1.6
6000 | 215963994001000 | 11.9 | 2.5
-}
The cost order of n^2 is as needed.
Bug GHC is somewhat 5 times faster.
I think, this factor of 5 is not so important.
But still, what may be its source?
The Haskell program sets n in its code, but this does not change
performance, because reading and parsing "6000" in Agda takes certainly
less than 0.1 sec.
Another question is on Standard library.
The functions decimalDigit?, filterStr, readNat
are used to parse n : Nat.
Has Standard library something for this?
Thanks,
------
Sergei
-------------- next part --------------
import Foreign.Haskell
open import IO.Primitive using (IO; readFiniteFile; _>>=_; putStrLn)
open import Data.String as Str using (String; toCostring)
open import Data.Char as Char using (Char)
open import Function using (_∘_; _$_; case_of_)
open import Relation.Nullary using (yes; no)
open import Relation.Nullary.Decidable using (⌊_⌋)
open import Relation.Unary using (Decidable)
open import Data.Product using (_×_; _,_; _,′_; proj₁; proj₂)
open import Data.List using (List; []; _∷_; map; _++_; reverse; filter; foldr)
open import Data.Nat using (ℕ; suc; _*_; _+_; _∸_; _≤_; _≤?_)
import Data.Nat.Show as NatShow
-- Prelude -----------------------------------------------------------------
concatStr : List String → String
concatStr = foldr Str._++_ ""
filterStr : ∀ {p} {P : Char → Set p} → Decidable P → String → String
filterStr P? = Str.fromList ∘ filter (⌊_⌋ ∘ P?) ∘ Str.toList
listPairs : ∀ {α β} {A : Set α} {B : Set β} → List A → List B → List (A × B)
listPairs [] _ = []
listPairs (x ∷ xs) ys = (map (_,_ x) ys) ++ (listPairs xs ys)
sum : List ℕ → ℕ
sum [] = 0
sum (n ∷ ns) = n + (sum ns)
downFrom : ℕ → List ℕ
downFrom 0 = []
downFrom (suc n) = n ∷ downFrom n
isDecimapDigit : Char → Set
isDecimapDigit c = 48 ≤ n × n ≤ 57 where
n = Char.toNat c
decimalDigit? : Decidable isDecimapDigit
decimalDigit? c =
let n = Char.toNat c
in
case ((48 ≤? n) ,′ (n ≤? 57)) of \
{ (yes le , yes le') → yes (le , le')
; (no 48≰n , _ ) → no (48≰n ∘ proj₁)
; (_ , no n≰57) → no (n≰57 ∘ proj₂)
}
charToDecDigitNat : Char -> ℕ
charToDecDigitNat c = (Char.toNat c) ∸ 48
readNat : List Char -> ℕ -- convert from decimal digit chars
readNat = toN ∘ map charToDecDigitNat ∘ reverse
where
toN : List ℕ -> ℕ
toN [] = 0
toN (j ∷ js) = j + (10 * (toN js))
stringToNat : String → ℕ
stringToNat = readNat ∘ Str.toList
-- NN-Show = pairShow Nat0.showInst Nat0.showInst
-- NL-Show = listShow Nat0.showInst
-- NNL-Show = listShow NN-Show
-- End - Prelude -----------------------------------------------------------
f : ℕ × ℕ → ℕ
f (m , n) = (m * m) ∸ (n * n)
test : ℕ → String
test n =
concatStr
("n = " ∷ (NatShow.show n) ∷
"\ns = " ∷ (NatShow.show s) ∷
-- "\nxs =\n " ∷ (Show.shownS NL-Show 0 xs) ∷
[]
)
where
xs = downFrom n
pairs = listPairs xs xs
s = sum $ map f pairs
main = (readFiniteFile "data.txt") >>= putStrLn ∘ toCostring ∘ h
where
h : String -> String
h str = test n
where
n = stringToNat $ filterStr decimalDigit? str
{- -----------------------------------------------------------------
Timing for Agda of September 16, 2016, ghc-7.10.2, 3 GHz computer
n | s (control) | time [sec]
| | Agda ghc-7.10.2 -O
--------------------------------------------------
1000 | 166499833500 | 0.3 | 0.04
2000 | 2665332667000 | 1.3 | 0.2
3000 | 13495498500500 | 3.0 | 0.4
4000 | 42655997334000 | 5.1 | 0.8
5000 | 104145829167500 | 8.0 | 1.6
6000 | 215963994001000 | 11.9 | 2.5
-}
{- Haskell program ----------------------------------
sum' :: [Integer] -> Integer
sum' [] = 0
sum' (n : ns) = n + (sum ns)
downFrom :: Integer -> [Integer]
downFrom 0 = []
downFrom n = (pred n) : downFrom (pred n)
minus :: Integer -> Integer -> Integer
minus m n =
if m <= n then 0 else m - n
f :: (Integer , Integer) -> Integer
f (m , n) = minus (m * m) (n * n)
test :: Integer -> String
test n = concat
["n = ", show n,
"\ns = ", show s
-- "\nxs =\n ", show xs
]
where
xs = downFrom n
pairs = [(x , y) | x <- xs, y <- xs]
s = sum' $ map f pairs
n = 6000 :: Integer
main = putStrLn (test n)
----------------------------------------------------
Making and running:
> ghc -O --make TT
> time ./TT
-}
More information about the Agda
mailing list