[racket] deceptive perfomance for typed racket in integer division
I am getting 6.8 ms without modifying the code.
When I change modulo to remainder I get 6.3 ms consistently.
Veer.
On Tue, Dec 11, 2012 at 8:33 PM, daniel rupis
<danielrupistralizavez at yahoo.es> wrote:
>
> I was comparing some code in Qi with that of sbcl, I posted a question in
> comp.lang.lisp asking for a way to improve the perfomance, WJ gave a typed
> racket version that was slower than sbcl and also much slower than cpp.
>
> Daniel Rupis wrote:
>
> Note: The code compute the number of primes below 30000 by a very
> brute force attack. (I know there are far better algorithms for this
> task :))
>
>
> (defun divisibleRec(I J)
> (declare (optimize (speed 3) (safety 0) (compilation-speed 0))
> (type (integer 0 300000) I J))
> (when (= J 1) (return-from divisibleRec nil))
> (if (zerop (rem I J)) t (divisibleRec I (1- J))))
>
>
> Typed Racket:
>
> #lang typed/racket
>
> (define: (divisible-rec (i : Integer) (j : Integer)) : Boolean
> (cond ((= j 1) #f)
> ((zero? (modulo i j)) #t)
> (else (divisible-rec i (sub1 j)))))
>
> (defun divisible(N)
> (declare (optimize (speed 3) (safety 0) (compilation-speed 0))
> (type (integer 0 300000) N))
> (divisibleRec N (1- N)))
>
>
> (define: (divisible (n : Integer)) : Boolean
> (divisible-rec n (sub1 n)))
>
> (defun totalprimes(k)
> (declare (optimize (speed 3) (safety 0) (compilation-speed 0)))
> (loop for n of-type (integer 0 300000) from 2 to k count (not
> (divisible n)))
>
> (define: (total-primes (k : Integer)) : Integer
> (for/sum ([n (in-range 2 (add1 k))])
> (if (divisible n) 0 1)))
>
> (displayln (total-primes 30999))
> 3340
>
> Thanks to all that responded.
>
> Results:
> Original code 5.280 seconds of real time
> Benjamin Kreuter code: 6.582 seconds of real time
> WJ code (typep racket) 10.544 seconds
>
> Conclusion:
>
> 1.- Typep racket is deceptively slow, I was expecting something better here
> (racket people are developing a math library with typep racket)
>
> 2.- Benjamin code is not a solution, it gives worse performance.
>
> 3.- Paul Khuong tell us that this problem will be here to stay for ever.
>
> What's the better way to include machine code like the one generate by C++ in
> Lisp. That is inline the code for example only for functions from integer to
> integers.
>
> Thanks again.
>
>
>
> I should say that I like racket, but I find macros in racket rather difficult.
> I can use macros in common-lisp but I still can't use racket macros. (I am
> trying to say that perhaps macros in racket are something difficult to grasp).
>
>
>
> Original Qi code and C++ code (30000 -> 30999)
>
> ------- Qi Code ----------------------------------------
>
> (define divisibleRec
> {number --> number --> boolean}
> I J -> (if (= J 1) false (if (= (fmod I J) 0) true (divisibleRec I (- J 1)))))
>
> (define divisible
> {number --> boolean}
> I -> (divisibleRec I (- I 1)))
>
> (define totalPrimesAcc
> {number --> number --> number}
> 1 Acc -> Acc
> I Acc -> (if (= (divisible I) false) (totalPrimesAcc (- I 1) (+ 1 Acc))
> (totalPrimesAcc (- I 1) Acc)))
>
> (define totalPrimes
> {number --> number}
> I -> (totalPrimesAcc I 0))
>
> (totalPrimes 30000)
>
> ----------------------------------------------------------------------
>
> #include <stdio.h>
>
> bool divisibleRec(int i, int j){
> if(j==1){ return false; }
> else if(i%j==0){ return true; }
> else{ return divisibleRec(i,j-1); }
> }
>
> bool divisible(int i){ return divisibleRec(i, i-1); }
>
> int main(void){
> int i, count =0;
> for(i=2; i<30000; ++i){
> if(divisible(i)==false){
> count = count+1;
> }
> }
> printf("number of primes = %d\n",count);
> return 0;
> }
> ----------------------------------------------------------
>
>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users