Controlling the P in REPL

Discussion of Common Lisp
Post Reply
[email protected]
Posts: 20
Joined: Sun Nov 28, 2010 10:34 pm

Controlling the P in REPL

Post by [email protected] » 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.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Controlling the P in REPL

Post by ramarren » Thu Feb 02, 2012 11:48 am

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)

[email protected]
Posts: 20
Joined: Sun Nov 28, 2010 10:34 pm

Re: Controlling the P in REPL

Post by [email protected] » 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.

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Controlling the P in REPL

Post by gugamilare » Fri Feb 03, 2012 7:48 am

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.

[email protected]
Posts: 20
Joined: Sun Nov 28, 2010 10:34 pm

Re: Controlling the P in REPL

Post by [email protected] » 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.

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Controlling the P in REPL

Post by gugamilare » Sat Feb 04, 2012 7:47 am

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

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

[email protected]
Posts: 20
Joined: Sun Nov 28, 2010 10:34 pm

Re: Controlling the P in REPL

Post by [email protected] » 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.

Post Reply