[Agda] gcd, toDecimal performance
Sergei Meshveliani
mechvel at botik.ru
Mon Mar 25 19:30:15 CET 2019
Concerning printing large Nat:
the following function show' : ℕ → String
prints large numbers many times faster than Data.Nat.Show.show,
it is `exponentially' faster.
So that the point III below can be fixed somewhat this way,
and it remains the point II of gcd.
---------------------------------------------------------------
LChar = List Char
toDigitChar : (n : ℕ) → Char
toDigitChar n =
Char.fromNat (n + 48)
1<10 : 1 < 10
1<10 = s≤s (s≤s z≤n)
{-# TERMINATING #-}
toDecimalChars : ℕ → LChar
toDecimalChars x = aux x []
where
aux : (n : ℕ) → LChar → LChar
aux 0 = ('0' ∷_)
aux (suc n) =
let q = (suc n) div 10 -- Only avoid _divMod_
r = (suc n) % 10 -- of the current Standard!
c = toDigitChar r
in
case q ≟ 0 of \ { (yes _) → (c ∷_)
; (no _) → aux q ∘ (c ∷_) }
show' : ℕ → String
show' = Str.fromList ∘ toDecimalChars
test : show' 1090 ≡ "1090"
test = refl
----------------------------------------------------------------------
--
SM
On Mon, 2019-03-25 at 18:53 +0300, Sergei Meshveliani wrote:
> Dear standard library developers,
>
> I wrote recently about the performance of divMod for Nat and rational
> arithmetics, and Ulf issued some comments.
>
> But now I discover news, when look into Dat.Nat/
> in the
> experimental lib branch for Agda-2.6.0-candidate.
>
> There appear _≡ᵇ_, _<ᵇ_, div-mod-helper
>
> which use built-ins from GHC.
> Also the attached test shows that mod (_%_) and _div_ are fast enough.
>
> (1) But gcd remains `exponentially' slow.
> This is strange. Because gcd is usually found by applying divMod a few
> times.
> This slow gcd will actually break rational arithmetic.
>
> (2) Printing Nat (in decimal digits) is `exponentially' slow.
> This is also strange. Because conversion from unary to decimal system
> can be written as something like applying (\n -> divMod n 10) a few
> times.
> Am I missing something?
>
> Can you, please, fix these two features?
> I guess this is not difficult, because standard library currently has
> all the needed fast functions.
>
> Please try the _attached test_.
>
> It
> reads n : Nat from data.txt (n = 10, 11, 12, ...);
>
> computes fs = factorials n = [0!, 1!, ..., n!]
> (12! is not so large);
> computes x % n, (x div n) % n for x <- fs;
> prints x % n, (x div n) % n for x <- fs.
>
> prints gcd! x n for x <- fs; -- II
> prints fs. -- III
>
>
> For n = 12, all this is done in a moment - except II and III.
> II takes very long,
> III takes very long.
>
> I guess this illustrates the conclusions (1) and (2).
> Does it?
>
> Can you, please, look into the subject?
> I have an impressions that these things can be fixed easily.
>
> Thanks,
>
> ------
> Sergei
>
>
>
>
>
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda
More information about the Agda
mailing list