Page 1 of 1

Controlling the P in REPL

Posted: Thu Feb 02, 2012 11:27 am
I am evaluating algorithms that produce large lists (larger than I want to scroll through in a SLIME buffer). For example, I have a function:

Code: Select all

(defun prime-list (n m)
  (declare (optimize (speed 0) (debug 0) (safety 0)))
  (declare (type fixnum n)
	   (type fixnum m))
 
  (let ((primes  (loop for i from 
		      ((lambda (c) (if (evenp c)
				       (+ c 1)
				       c)) n) 
		    to m by 2 
		    when (primep i) 
		    collect i)))
    (if (< n 3)
	(append '(2) primes)
	primes)))
I am timing it and exploring how playing with the type declarations and optimizations effect it. I typically execute it with

Code: Select all

(time (prime-list 0 200000))
which gives me a useful figure of merit for how the optimizations are changing. Unfortunately it returns a list with 17985 primes, which I don't really care about (but do need as part of a larger system).

Is there a way to suppress the P in REPL? I am using SBCL under SLIME if that matters.

Re: Controlling the P in REPL

Posted: Thu Feb 02, 2012 11:48 am
by ramarren
For controlling the printer output see variables in the printer dictionary, especially in this case *print-level*/*print-length*. You could also wrap the form inside TIME with something, I personally wrap large list-generating function with LENGTH as a simple consistency check. You could write a macro to do that, but using

Code: Select all

(time (length (prime-list 0 200000)))
doesn't seem particularly onerous.

Also, why would you write

Code: Select all

((lambda (c) (if (evenp c)
                 (+ c 1)
                 c)) n)
when it is functionally equivalent to just

Code: Select all

(if (evenp n)
    (+ n 1)
    n)

Re: Controlling the P in REPL

Posted: Thu Feb 02, 2012 12:42 pm
Ramarren wrote:For controlling the printer output see variables in the printer dictionary, especially in this case *print-level*/*print-length*. You could also wrap the form inside TIME with something, I personally wrap large list-generating function with LENGTH as a simple consistency check. You could write a macro to do that, but using

Code: Select all

(time (length (prime-list 0 200000)))
doesn't seem particularly onerous.
Good idea. I need to learn macros, sounds like a good way to start, even if trivial...
Ramarren wrote: Also, why would you write

Code: Select all

((lambda (c) (if (evenp c)
                 (+ c 1)
                 c)) n)
when it is functionally equivalent to just

Code: Select all

(if (evenp n)
    (+ n 1)
    n)
Because I didn't think of it. I have been writing in LISP for about two weeks now, give me a chance to catch up :D

I did the first thing that came to mind since it was only executed once I didn't think about it much after it worked.

Re: Controlling the P in REPL

Posted: Fri Feb 03, 2012 7:48 am
by gugamilare
To suppress the output is very easy, just call:

Code: Select all

(time (progn (prime-list 0 200000) nil))
Let me present another criticism to your code. I don't know what your objective is, but, if you are trying to implement prime-list efficiently, you are not doing a good job because your algorithm is highly inneficient. I recommend you to implement the Sieve of Eratosthenes.

Re: Controlling the P in REPL

Posted: Fri Feb 03, 2012 12:15 pm
gugamilare wrote: Let me present another criticism to your code. I don't know what your objective is, but, if you are trying to implement prime-list efficiently, you are not doing a good job because your algorithm is highly inneficient. I recommend you to implement the Sieve of Eratosthenes.
You are correct. If the only purpose was to generate a large range of primes, the a sieve method would be much faster. However I am working on primality tests.
The goal of this piece of code is to test the primep predicate which I use extensively elsewhere.

Re: Controlling the P in REPL

Posted: Sat Feb 04, 2012 7:47 am
by gugamilare
I thought so, but I wasn't sure :)

I'm curious, are you implementing AKS primality test?

Re: Controlling the P in REPL

Posted: Sat Feb 04, 2012 8:11 am
gugamilare wrote:I thought so, but I wasn't sure :)

I'm curious, are you implementing AKS primality test?
No, I am mostly trying to learn how to optimize integer arithmetic in LISP. I am working my way through the EulerProject problems. Primality testing is very integer arithmetic intensive and serves as a good learning ground. I have been getting lots of strange results playing with type declarations and various SBCL (declare (optimize n) (debug m) (safety o)) settings. That is why I don't really pay attention to the results, just the time and processor cycles.

I like your progn approach, it puts a lot lower overhead on the timing.