This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Controlling the P in REPL

7 posts · 3406 views

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:
(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
(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

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
(time (length (prime-list 0 200000)))
doesn't seem particularly onerous.

Also, why would you write
((lambda (c) (if (evenp c)
                 (+ c 1)
                 c)) n)
when it is functionally equivalent to just
(if (evenp n)
    (+ n 1)
    n)

Re: Controlling the P in REPL

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
(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
((lambda (c) (if (evenp c)
                 (+ c 1)
                 c)) n)
when it is functionally equivalent to just
(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

To suppress the output is very easy, just call:
(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

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

I thought so, but I wasn't sure :)

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

Re: Controlling the P in REPL

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.