Collecting the time and space results produced by `time` macro? - lisp

Common Lisp provide a time macro for finding out how long a form takes to execute, and it prints the information to the trace output:
time evaluates form in the current environment (lexical and dynamic). … time prints various timing data and other information to trace output.
The nature and format of the printed information is
implementation-defined. Implementations are encouraged to provide such
information as elapsed real time, machine run time, and storage
management statistics.
For instance:
(time (length (make-array 1000000)))
Real time: 0.0140014 sec.
Run time: 0.0 sec.
Space: 4000008 Bytes
GC: 1, GC time: 0.0 sec.
Is there a way to collect these parameters and push them step by step into some stack or list and return it from a function?

Some things are standard: get-internal-run-time and get-internal-real-time:
(defvar *my-timings* nil)
(let ((run (get-internal-run-time))
(real (get-internal-real-time)))
(multiple-value-prog1 (my-code)
(push (cons (- (get-internal-run-time) run)
(- (get-internal-real-time) real))
*my-timings*)))
Others are not (space and GC count), you need to find the implementation-specific versions.
You might also consider using with-timing - it provides progress reports including ETA.
Incidentally, in your code, memory allocation (make-array) dwarfs length (which is slot access for an array).

Related

Is it possible to limit the maximum number of buffers saved with desktop?

I use (desktop-save-mode 1) in my .emacs. After some time of working with it my .emacs.desktop contains many (desktop-create-buffer...) entries which slow down startup terribly. Is it possible to limit the number of saved buffers to some arbitrary number?
For total control, you could advise the function desktop-save-buffer-p such that it returns nil for all the buffers you don't want to be saved.
By default that uses three user options:
desktop-buffers-not-to-save (regexp)
desktop-files-not-to-save (regexp)
desktop-modes-not-to-save (list)
Those don't directly help you cap the number of buffers saved to a specific limit, but they may prove useful regardless.
You might adapt code from midnight.el (e.g. a variant of clean-buffer-list which just returns a buffer list rather than killing buffers) to make use of existing code for identifying old/unnecessary buffers.

How to read space separated integers in racket

I looked at the documentation https://docs.racket-lang.org/reference/input-and-output.html but I find it to be very confusing and I feel like it contains a lot of extra information I don't need for such a simple task.
I would like to read two space separated integers and store them in variables.
example input:
1 2
I would like to define and x and y whose values are 1 and 2 respectively.
There are a lot of ways to do this. I’ll give you three.
Option 1: Use the built-in read
The read function reads s-expressions. Conveniently, integers are valid s-expressions, and it skips whitespace, too. This means you can just call read twice on an input port to produce two datums:
> (let ([in (open-input-string "1 2")])
(values (read in) (read in)))
1
2
This has a drawback, though: there are a lot of things that are valid s-expressions that aren’t numbers, so you might get a lot of garbage back if you’re not careful. For example:
> (let ([in (open-input-string "#f (hello world)")])
(values (read in) (read in)))
#f
'(hello world)
You’d probably need to do some post-processing to ensure what you get back is what you expect. This also won’t necessarily consume all the input, so if it’s important there’s nothing else after the numbers, you’d need to check that separately, too.
Option 2: Use a regular expression
Regular expressions are a pretty easy way to handle simple cases like this. In this example, the regexp literal #px"^(\\d+) (\\d+)$" is a simple way to express the pattern you mention in your question. You can use this to extract the numeric parts of the string:
> (regexp-match #px"^(\\d+) (\\d+)$" "1 2")
'("1 2" "1" "2")
You can combine this with string->number to get numbers out:
> (let ([matches (regexp-match #px"^(\\d+) (\\d+)$" "1 2")])
(values (string->number (second matches))
(string->number (third matches))))
1
2
This has the advantage of ensuring the input matches precisely, and it’s safe, fast, and simple. However, one downside is that it will not provide good error messages if the parsing fails, regexp-match will simply produce #f.
Option 3: Use a parser combinator library
Racket has a number of libraries designed for parsing. These can scale to parsing far more complicated things that two numbers, but they also work fine for simple situations. I will show an example using megaparsack, since it’s my library, and I like it.
You can use megaparsack to write a parser that parses two integers separated by a space:
(require data/applicative
data/monad
megaparsack
megaparsack/text)
(define 2-integers/p
(do [x <- integer/p]
(char/p #\space)
[y <- integer/p]
(pure (cons x y))))
This parser is obviously more complicated than the regexp, but it also does more, and it’s much more extensible and composable. You can use this parser to get the numbers you want:
> (parse-result! (parse-string 2-integers/p "1 2"))
'(1 . 2)
However, unlike the regular expression, it will automatically provide good error messages when a parse fails:
> (parse-result! (parse-string 2-integers/p "1 "))
string:1:1: parse error
unexpected: end of input
expected: integer

bignum multiplication in SBCL

Yesterday I tried to figure out the size of the new Mersenne Prime (http://www.mersenne.org/primes/?press=M74207281)
on my SBCL box (v. 1.3.2 (x64), Windows 10, Dell Core i5 8GB RAM)
After almost one hour I gave up and interrupted the calculation.
Below the resulting screen:
This is SBCL 1.3.2, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
WARNING: the Windows port is fragile, particularly for multithreaded
code. Unfortunately, the development team currently lacks the time
and resources this platform demands.
* (- (expt 2 74207281) 1)
debugger invoked on a SB-SYS:INTERACTIVE-INTERRUPT in thread
'#<THREAD "main thread" RUNNING {1002A9BD03}>:'
Interactive interrupt at #x100008BD9E.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE] Return from SB-WIN32::SIGINT.
1: [ABORT ] Exit debugger, returning to top level.
1
(SB-BIGNUM:MULTIPLY-BIGNUMS #<unavailable argument> #<unavailable argument>)
0] 1
To me this was interesting, because I tried the same expression on Racket 6.4, on the same machine,
And it took (comparatively) only 1m08s to start spitting numbers.
In Haskell, again on the same machine, with
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> 2^74207281 - 1
it took only 8s to start the numbers' exhibition.
Despite the fact that it could be a bug, do anyone know how SBCL do bignum multiplication? Would its way of doing it be the possible cause of delay?
Thanks in advance!
*EDIT
After Sylvester´s comment, maybe the right question is: What is preventing the big number from been shown? Yes, it is really big (Racket and Haskell versions wrote it to a text file of 21 MB), but it seems that there is something more than its size preventing the task´s completion.
The actual calculation is pretty fast on my machine, less than a second in fact.
(defun make-prime ()
(declare (optimize (safety 0)(debug 0)(speed 3)))
(time (- (expt 2 74207281) 1)))
(defparameter *prime* (make-prime))
;Evaluation took:
; 0.000 seconds of real time
; 0.000017 seconds of total run time (0.000015 user, 0.000002 system)
; 100.00% CPU
; 1,292 processor cycles
; 0 bytes consed
; ==> *PRIME*
However printing the number is a whole other matter.

Is Lisp the only language with REPL?

There are languages other than Lisp (ruby, scala) that say they use REPL (Read, Eval, Print, Loop), but it is unclear whether what is meant by REPL is the same as in Lisp. How is Lisp REPL different from non-Lisp REPL?
The idea of a REPL comes from the Lisp community. There are other forms of textual interactive interfaces, for example the command line interface. Some textual interfaces also allow a subset of some kind of programming language to be executed.
REPL stands for READ EVAL PRINT LOOP: (loop (print (eval (read)))).
Each of the four above functions are primitive Lisp functions.
In Lisp the REPL is not a command line interpreter (CLI). READ does not read commands and the REPL does not execute commands. READ reads input data in s-expression format and converts it to internal data. Thus the READ function can read all kinds of s-expressions - not just Lisp code.
READ reads a s-expression. This is a data-format that also supports encoding source code. READ returns Lisp data.
EVAL takes Lisp source code in the form of Lisp data and evaluates it. Side effects can happen and EVAL returns one or more values. How EVAL is implemented, with an interpreter or a compiler, is not defined. Implementations use different strategies.
PRINT takes Lisp data and prints it to the output stream as s-expressions.
LOOP just loops around this. In real-life a REPL is more complicated and includes error handling and sub-loops, so-called break loops. In case of an error one gets just another REPL, with added debug commands, in the context of the error. The value produced in one iteration also can be reused as input for the next evaluation.
Since Lisp is both using code-as-data and functional elements, there are slight differences to other programming languages.
Languages that are similar, those will provide also similar interactive interfaces. Smalltalk for example also allows interactive execution, but it does not use a data-format for I/O like Lisp does. Same for any Ruby/Python/... interactive interface.
Question:
So how significant is the original idea of READing EXPRESSIONS, EVALuating them and PRINTing their values? Is that important in relation to what other languages do: reading text, parsing it, executing it, optionally print something and optionally printing a return value? Often the return value is not really used.
So there are two possible answers:
a Lisp REPL is different to most other textual interactive interfaces, because it is based on the idea of data I/O of s-expressions and evaluating these.
a REPL is a general term describing textual interactive interfaces to programming language implementations or subsets of those.
REPLs in Lisp
In real implementations Lisp REPLs have a complex implementation and provide a lot of services, up to clickable presentations (Symbolics, CLIM, SLIME) of input and output objects. Advanced REPL implementations are for example available in SLIME (a popular Emacs-based IDE for Common Lisp), McCLIM, LispWorks and Allegro CL.
Example for a Lisp REPL interaction:
a list of products and prices:
CL-USER 1 > (setf *products* '((shoe (100 euro))
(shirt (20 euro))
(cap (10 euro))))
((SHOE (100 EURO)) (SHIRT (20 EURO)) (CAP (10 EURO)))
an order, a list of product and amount:
CL-USER 2 > '((3 shoe) (4 cap))
((3 SHOE) (4 CAP))
The price for the order, * is a variable containing the last REPL value. It does not contain this value as a string, but the real actual data.
CL-USER 3 > (loop for (n product) in *
sum (* n (first (second (find product *products*
:key 'first)))))
340
But you can also compute Lisp code:
Let's take a function which adds the squares of its two args:
CL-USER 4 > '(defun foo (a b) (+ (* a a) (* b b)))
(DEFUN FOO (A B) (+ (* A A) (* B B)))
The fourth element is just the arithmetic expression. * refers to the last value:
CL-USER 5 > (fourth *)
(+ (* A A) (* B B))
Now we add some code around it to bind the variables a and b to some numbers. We are using the Lisp function LIST to create a new list.
CL-USER 6 > (list 'let '((a 12) (b 10)) *)
(LET ((A 12) (B 10)) (+ (* A A) (* B B)))
Then we evaluate the above expression. Again, * refers to the last value.
CL-USER 7 > (eval *)
244
There are several variables which are updated with each REPL interaction. Examples are *, ** and *** for the previous values. There is also + for the previous input. These variables have as values not strings, but data objects. + will contain the last result of the read operation of the REPL. Example:
What is the value of the variable *print-length*?
CL-USER 8 > *print-length*
NIL
Let's see how a list gets read and printed:
CL-USER 9 > '(1 2 3 4 5)
(1 2 3 4 5)
Now let's set the above symbol *print-length* to 3. ++ refers to the second previous input read, as data. SET sets a symbols value.
CL-USER 10 > (set ++ 3)
3
Then above list prints differently. ** refers to the second previous result - data, not text.
CL-USER 11 > **
(1 2 3 ...)
Seeing as the concept of a REPL is to just Read, Eval, Print & Loop it's not too suprising that there are REPLs for many languages:
C/C++
C#/LINQ
Erlang
Haskell (on windows)
Java
Javascript
Julia
Perl
Python
Ruby
Scala
Smalltalk -- I learned it on a REPL!
I think it is interesting to compare two approaches. A bare bones REPL loop in a Lisp system would look like this:
(loop (print (eval (read))))
Here are two actual Forth implementations of a REPL loop. I'm leaving nothing out here -- this is the full code to these loops.
: DO-QUIT ( -- ) ( R: i*x -- )
EMPTYR
0 >IN CELL+ ! \ set SOURCE-ID to 0
POSTPONE [
BEGIN \ The loop starts here
REFILL \ READ from standard input
WHILE
INTERPRET \ EVALUATE what was read
STATE # 0= IF ." OK" THEN \ PRINT
CR
REPEAT
;
: quit
sp0 # 'tib !
blk off
[compile] [
begin
rp0 # rp!
status
query \ READ
run \ EVALUATE
state # not
if ." ok" then \ PRINT
again \ LOOP
;
Lisp and Forth do completely different things, particularly in the EVAL part, but also in the PRINT part. Yet, they share the fact that a program in both languages is run by feeding its source code to their respective loops, and in both cases code is just data (though in Forth case it is more like data is also code).
I suspect what anyone saying only LISP has a REPL is that the READ loop reads DATA, which is parsed by EVAL, and a program is created because CODE is also DATA. This distinction is interesting in many respects about the difference between Lisp and other languages, but as far as REPL goes, it doesn't matter at all.
Let's consider this from the outside:
READ -- returns input from stdin
EVAL -- process said input as an expression in the language
PRINT -- print EVAL's result
LOOP -- go back to READ
Without going into implementation details, one can't distinguish a Lisp REPL from, for example, a Ruby REPL. As functions, they are the same.
I guess you could say that Scala's "REPL" is an "RCRPL": Read, Compile, Run, Print. But since the compiler is kept "hot" in memory, it's pretty fast for ongoing interactions--it just takes a few seconds to start up.
There are a number of people that consider a REPL to needs to behave exactly like it does in LISP, or it's not a true REPL. Rather, they consider it something different, like a CLI (command line interpreter). Honestly, I tend to think that if it follows the basic flow of:
read input from the user
evaluate that input
print the output
loop back to the read
then it's a REPL. As noted, there are a lot of languages that have the above capability.
See this reddit thread for an example of such a discussion.
How is Lisp REPL different from non-Lisp REPL?
Let's compare Common Lisp's REPL with Python's IPython.
The main two points are:
Lisp is an image-based language. There is no need to restart the process/the REPL/the whole app after a change. We compile our code function by function (with compiler warnings etc).
we don't loose state. Even more, when we update class definitions, our objects in the REPL are also updated, following rules we have control upon. That way we can hot-reload code in a running system.
In Python, typically, you start IPython or you are dropped into ipdb. You define some data until you try out your new function. You edit your source, and you want to try again, so you quit IPython and you start the whole process again. In Lisp (Common Lisp mainly), not at all, it's all more interactive.
There's a nice project called multi-repl which exposes various REPLs via Node.JS:
https://github.com/evilhackerdude/multi-repl
If you look at the list of supported languages, it's quite clear that not only Lisp has the concept of a REPL.
clj (clojure)
ghci (ghc)
ipython
irb (ruby)
js (spidermonkey)
node
python
sbcl
v8
In fact implementing a trivial one in Ruby is fairly easy:
repl = -> prompt { print prompt; puts(" => %s" % eval(gets.chomp!)) }
loop { repl[">> "] }

In lisp how can I measure and capture the time spent evaluating an expression?

I want to capture the results of a call to the time macro in order to gather multiple measurements and process them. I tried to locally setf the standard output and redirect it to a string but it didn't work with the time macro. Maybe it is wrong, but what I tried is:
(with-output-to-string (str)
(let ((*standard-output* str))
(time (test-with-size 40))))
The questions:
Is a way to capture the output of time?
If not, can I capture the slime-profile-report command's output?
If none of the above works, how can I measure the time spent evaluating an arbitrary expression?
What I want to accomplish is to measure the run-time of an algorithm as the size of the input increases so for each input size (ranging from 1 to 100) I will measure a lot of times and keep the average. Then I want to plot the results. Plotting is easy, and I have found many ways in Cliki, but how can I gather the results?
I am using CLISP and CCL.
EDIT: Paul Nathan pointed that the time macro outputs to *trace-output* which is a solution. I would like a nicer, simpler, solution though, because with this one, I have to parse an implementation specific trace.
If you want to capture the text, you need to use the right stream. The ANSI CL standard says that TIME prints to trace output.
So this would give you the text as a string.
(with-output-to-string (*trace-output*)
(time (sin 40.0)))
You could also write your own macro using the time primitives. See 25.1.4.3 Internal Time to get numeric data.