@cindex benchmarking
You can measure the time it takes to evaluate individual Emacs Lisp
forms using the @file{benchmark} library. See the macros
-@code{benchmark-run} and @code{benchmark-run-compiled} in
-@file{benchmark.el}. You can also use the @code{benchmark} command
-for timing forms interactively.
+@code{benchmark-run}, @code{benchmark-run-compiled} and
+@code{benchmark-progn} in @file{benchmark.el}. You can also use the
+@code{benchmark} command for timing forms interactively.
@c Not worth putting in the printed manual.
@ifnottex
\f
* Lisp Changes in Emacs 27.1
++++
+** New macro 'benchmark-progn'
+This macro works like 'progn', but messages how long it takes to
+evaluate the body forms. The value of the last form is the return
+value.
+
** New function 'read-char-with-history'.
This function works like 'read-char', but maintains a history that can
be navigated via the 'M-p'/'M-n' keystrokes.
(message "Elapsed time: %fs (%fs in %d GCs)" (car result)
(nth 2 result) (nth 1 result)))))
+;;;###autoload
+(defmacro benchmark-progn (&rest body)
+ "Evaluate BODY and message the time taken.
+The return value is the value of the final form in BODY."
+ (declare (debug body) (indent 0))
+ (let ((value (make-symbol "value"))
+ (start (make-symbol "start"))
+ (gcs (make-symbol "gcs"))
+ (gc (make-symbol "gc")))
+ `(let ((,gc gc-elapsed)
+ (,gcs gcs-done)
+ (,start (current-time))
+ (,value (progn
+ ,@body)))
+ (message "Elapsed time: %fs%s"
+ (float-time (time-since ,start))
+ (if (> (- gcs-done ,gcs) 0)
+ (format " (%fs in %d GCs)"
+ (- gc-elapsed ,gc)
+ (- gcs-done ,gcs))
+ ""))
+ ;; Return the value of the body.
+ ,value)))
+
(provide 'benchmark)
;;; benchmark.el ends here