view lisp/emacs-lisp/benchmark.el @ 69713:75b06a7624a1

* images/README: Update with following information. * images/data-save.xpm, images/mail/flag-for-followup.xpm: * images/zoom-in.xpm, images/zoom-out.xpm: New images from GNOME 2.12. * images/contact.pbm, images/data-save.pbm, images/delete.pbm: * images/mail/flag-for-followup.pbm, images/mail/inbox.pbm: * images/mail/move.pbm, images/next-page.pbm, images/zoom-out.pbm: New bitmaps for new images. * images/refresh.xpm, images/sort-ascending.xpm, * images/sort-descending.xpm: Update with GTK 2.x images. Note that the default GTK icons are not overridden by the GNOME theme due to a bug which was fixed in GNOME 2.15. Once GNOME 2.16 is in wide circulation, then the GTK icons should be replaced with the equivalent GNOME icons. Until then, we should be consistent with GTK first, then GNOME. * images/mail/repack.xpm, images/mail/reply-from.xpm: * images/mail/reply-to.xpm, images/search-replace.xpm: * images/separator.xpm, images/show.xpm: Update custom icons to be closer to their GNOME counterparts. * images/attach.pbm, images/exit.pbm, images/mail/compose.pbm: * images/mail/repack.pbm, images/mail/reply-all.pbm: * images/mail/reply-from.pbm, images/mail/reply-to.pbm: * images/mail/reply.pbm, images/mail/send.pbm, images/show.pbm: * images/search-replace.pbm: Update bitmaps. * images/execute.pbm, images/execute.xpm, images/fld-open.pbm: * images/fld-open.xpm, images/highlight.pbm, images/highlight.xpm: * images/mail.pbm, images/mail.xpm, images/mail/alias.pbm: * images/mail/alias.xpm, images/mail/refile.pbm: * images/mail/refile.xpm, images/page-down.pbm, images/page-down.xpm: * images/widen.pbm, images/widen.xpm: Remove custom MH-E icons since MH-E is now using the equivalent GTK/GNOME icons.
author Bill Wohler <wohler@newt.com>
date Tue, 28 Mar 2006 19:15:30 +0000
parents 067115a6e738
children 7a3f13e2dd57 c5406394f567
line wrap: on
line source

;;; benchmark.el --- support for benchmarking code

;; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.

;; Author: Dave Love  <fx@gnu.org>
;; Keywords: lisp, extensions

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:

;; Utilities for timing the execution of forms, including the time
;; taken for GC.  Note that prior to timing code you may want to
;; ensure things like:  there has just been a GC, the relevant code is
;; already loaded (so that there's no overhead from autoloading etc.),
;; and the code is compiled if appropriate (but see
;; `benchmark-run-compiled').

;;; Code:

(defmacro benchmark-elapse (&rest forms)
  "Return the time in seconds elapsed for execution of FORMS."
  (let ((t1 (make-symbol "t1"))
	(t2 (make-symbol "t2")))
    `(let (,t1 ,t2)
       (setq ,t1 (current-time))
       ,@forms
       (setq ,t2 (current-time))
       (+ (* (- (car ,t2) (car ,t1)) 65536.0)
	  (- (nth 1 ,t2) (nth 1 ,t1))
	  (* (- (nth 2 ,t2) (nth 2 ,t1)) 1.0e-6)))))
(put 'benchmark-elapse 'edebug-form-spec t)
(put 'benchmark-elapse 'lisp-indent-function 0)

;;;###autoload
(defmacro benchmark-run (&optional repetitions &rest forms)
  "Time execution of FORMS.
If REPETITIONS is supplied as a number, run forms that many times,
accounting for the overhead of the resulting loop.  Otherwise run
FORMS once.
Return a list of the total elapsed time for execution, the number of
garbage collections that ran, and the time taken by garbage collection.
See also `benchmark-run-compiled'."
  (unless (natnump repetitions)
    (setq forms (cons repetitions forms)
	  repetitions 1))
  (let ((i (make-symbol "i"))
	(gcs (make-symbol "gcs"))
	(gc (make-symbol "gc")))
    `(let ((,gc gc-elapsed)
	   (,gcs gcs-done))
       (list ,(if (> repetitions 1)
		  ;; Take account of the loop overhead.
		  `(- (benchmark-elapse (dotimes (,i ,repetitions)
					  ,@forms))
		      (benchmark-elapse (dotimes (,i ,repetitions))))
		`(benchmark-elapse ,@forms))
	     (- gcs-done ,gcs)
	     (- gc-elapsed ,gc)))))
(put 'benchmark-run 'edebug-form-spec t)
(put 'benchmark-run 'lisp-indent-function 2)

;;;###autoload
(defmacro benchmark-run-compiled (&optional repetitions &rest forms)
  "Time execution of compiled version of FORMS.
This is like `benchmark-run', but what is timed is a funcall of the
byte code obtained by wrapping FORMS in a `lambda' and compiling the
result.  The overhead of the `lambda's is accounted for."
  (unless (natnump repetitions)
    (setq forms (cons repetitions forms)
	  repetitions 1))
  (let ((i (make-symbol "i"))
	(gcs (make-symbol "gcs"))
	(gc (make-symbol "gc"))
	(code (byte-compile `(lambda () ,@forms)))
	(lambda-code (byte-compile `(lambda ()))))
    `(let ((,gc gc-elapsed)
	   (,gcs gcs-done))
       (list ,(if (> repetitions 1)
		  ;; Take account of the loop overhead.
		  `(- (benchmark-elapse (dotimes (,i ,repetitions)
					  (funcall ,code)))
		      (benchmark-elapse (dotimes (,i ,repetitions)
					  (funcall ,lambda-code))))
		`(benchmark-elapse (funcall ,code)))
	     (- gcs-done ,gcs) (- gc-elapsed ,gc)))))
(put 'benchmark-run-compiled 'edebug-form-spec t)
(put 'benchmark-run-compiled 'lisp-indent-function 2)

;;;###autoload
(defun benchmark (repetitions form)
  "Print the time taken for REPETITIONS executions of FORM.
Interactively, REPETITIONS is taken from the prefix arg.  For
non-interactive use see also `benchmark-run' and
`benchmark-run-compiled'."
  (interactive "p\nxForm: ")
  (let ((result (eval `(benchmark-run ,repetitions ,form))))
    (if (zerop (nth 1 result))
	(message "Elapsed time: %fs" (car result))
      (message "Elapsed time: %fs (%fs in %d GCs)" (car result)
	       (nth 2 result) (nth 1 result)))))

(provide 'benchmark)

;;; arch-tag: be570e24-4b51-4784-adf3-fa2b56c31946
;;; benchmark.el ends here