We can speed up the function / : (INT, INT)->FRAC INT by using Lisp intrinsic.
Note that in Lisp, when you create a fraction by '(/ x y)', the gcd of x and y is not computed, aka Lisp uses "lazy" representation. Also note that you can't use '_/(a,b)$Lisp' in Spad because in Spad '/' may indicate 'reduce'. See the benchmark test I put in the end, this change gives a 50% boost: 0.31s (div1) vs. 0.21s (div2). I think that's because the new version has much fewer function calls. --- a/src/algebra/fraction.spad +++ b/src/algebra/fraction.spad @@ -367,10 +367,17 @@ x.den := xd :: S d - nn : S / dd : S == - zero? dd => error "division by zero" - cancelGcd(z := [nn, dd]) - normalize z + if S is Integer then + opdiv ==> _/$Lisp + nn : S / dd : S == + zero? dd => error "division by zero" + tmp : SExpression := opdiv(nn, dd) + [NUMERATOR(tmp)$Lisp pretend S, DENOMINATOR(tmp)$Lisp pretend S] + else + nn : S / dd : S == + zero? dd => error "division by zero" + cancelGcd(z := [nn, dd]) + normalize z x + y == zero? y => x ============ Benchmark for this change: )abbrev package TEST1 Test1 Test1() : Exports == Impl where Exports == with div1 : () -> Boolean div2 : () -> Boolean Impl == add n ==> 10^6 opdiv ==> _/$Lisp l1 : Vector Integer := vector [random x for x in 1..n] l2 : Vector Integer := vector [1+random x for x in 1..n] l3 : Vector Fraction Integer := new(n, 0) l4 : Vector Fraction Integer := new(n, 0) div1() == for i in 1..n repeat l3.i := l1.i/l2.i true div2() == for i in 1..n repeat tmp1 : SExpression := opdiv(l1.i,l2.i) l4.i := CONS(NUMERATOR(tmp1)$Lisp,DENOMINATOR(tmp1)$Lisp)$Lisp true -- You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group. To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel+unsubscr...@googlegroups.com. To post to this group, send email to fricas-devel@googlegroups.com. Visit this group at https://groups.google.com/group/fricas-devel. For more options, visit https://groups.google.com/d/optout.