view lisp/emacs-lisp/benchmark.el @ 82988:f82e3a6f5ccb

A few more bugfixes and new features. (Sigh.) I obviously need to remember to separate individual changes to multiple commits. src/emacsclient.c: Improved error handling. (decode_options): Changed frame option (again) from -f to -t. (print_help_and_exit): Ditto. (copy_from_to): Check EINTR after write, not EAGAIN. Removed SIGIO hack. (pty_conversation): Handle errors transmitted through the socket. Handle pty errors by not reading from it anymore. (main): Restore correct errno after socket_status failed. Send -tty on -t, not -pty. lisp/server.el (server-process-filter): Watch -tty, not -pty. Use make-frame-on-tty instead of make-terminal-frame. Don't set newframe to t if make-frame-on-tty failed. Don't delete frames here. Print correct message when there are no files to edit, but a new frame was requested. (server-sentinel): Delete the frame after the process. (server-handle-delete-frame): New function for delete-frame-functions. (server-start): Add server-handle-delete-frame to delete-frame-functions. (server-buffer-done): Don't delete frames here. src/alloc.c (mark_ttys): Add prototype. (Fgarbage_collect): Call mark_ttys. src/emacs.c: (shut_down_emacs): Don't flush stdout before reset_sys_modes(). src/process.c (add_keyboard_wait_descriptor_called_flag): Removed. (add_keyboard_wait_descriptor): Removed stdin hack. src/sysdep.c: Unconditionally include sysselect.h. (old_fcntl_flags): Changed to an array. (init_sigio, reset_sigio): Use it. (narrow_foreground_group, widen_foreground_group): Use setpgid, not setpgrp. (old_fcntl_owner): Changed to an array. (init_sys_modes, reset_sys_modes): Use it. Fix fsync() and reset_sigio() calls. src/term.c (Qframe_tty_name, Qframe_tty_type): New variables. (syms_of_term): Initialize them. (Fframe_tty_name, Fframe_tty_type): New functions. (term_init): Call add_keyboard_wait_descriptor(). (Fdelete_tty): New function. (delete_tty): Call delete_keyboard_wait_descriptor(). (get_current_tty): Removed. (mark_ttys): New function. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-28
author Karoly Lorentey <lorentey@elte.hu>
date Wed, 31 Dec 2003 05:09:29 +0000
parents 695cf19ef79e
children 18a818a2ee7c 375f2633d815
line wrap: on
line source

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

;; Copyright (C) 2003  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., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, 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