diff lisp/utils/bench.el @ 80:1ce6082ce73f r20-0b90

Import from CVS: tag r20-0b90
author cvs
date Mon, 13 Aug 2007 09:06:37 +0200
parents 54cc21c15cbb
children 6a378aca36af
line wrap: on
line diff
--- a/lisp/utils/bench.el	Mon Aug 13 09:05:44 2007 +0200
+++ b/lisp/utils/bench.el	Mon Aug 13 09:06:37 2007 +0200
@@ -1,8 +1,16 @@
-;;; bench.el --- a crude benchmark for emacsen
+;;; bench.el --- benchmarking utility for emacsen
+
 ;; Copyright (C) 1987,88,89,90,93,94,95,96 Free Software Foundation, Inc.
+;; $Id: bench.el,v 1.2 1997/01/11 20:14:12 steve Exp $	
+;; $Source: /afs/informatik.uni-tuebingen.de/local/web/xemacs/xemacs-cvs/XEmacs/xemacs/lisp/utils/Attic/bench.el,v $
+;; $Revision: 1.2 $
+;; $Author: steve $
+;; $Date: 1997/01/11 20:14:12 $
 
 ;; Author: Shane Holder <holder@rsn.hp.com>
 ;; Adapted-By: Steve Baur <steve@altair.xemacs.org>
+;; Further adapted by: Shane Holder <holder@rsn.hp.com>
+;; Keywords: internal, maint
 
 ;; This file is part of XEmacs.
 
@@ -23,33 +31,332 @@
 
 ;;; Commentary:
 
+;; Adapted from Shane Holder's bench.el by steve@altair.xemacs.org.
+
 ;; To run
-;; Extract the shar file in /tmp, or modify bench-large-lisp-file to
-;; point to the gnus-bench.el file.
-;; At the shell prompt emacs -q --no-site-file <= don't load users .emacs or
-;;    site-file
+;; Extract the shar file in /tmp, or modify bench-lisp-file to
+;; point to the gnus.el file.
+;; At the shell prompt emacs -q --no-site-file <= don't load users .emacs or site-file
 ;; M-x byte-compile-file "/tmp/bench.el"
 ;; M-x load-file "/tmp/bench.elc"
 ;; In the scratch buffer (bench 1)
 
+
+;; All bench marks must be named bench-mark-<something>
+;; Results are put in bench-mark-<something-times which is a list of
+;;  times for the runs.
+;; If the bench mark is not simple then there needs to be a
+;;  corresponding bench-handler-<something>
+
 ;;; Code:
 
 ;; Use elp to profile benchmarks
-(require 'elp)
-(eval-when-compile (require 'cl))	; Emacs doesn't have when and cdar
+(require 'cl)				;Emacs doesn't have when and cdar
+
+;-----------------------------------------------------------------------------
+(defvar bench-mark-hanoi-times nil)
+
+(defun bench-handler-hanoi (times)
+  (let ((start-time))
+  (while (> times 0)
+;    (setq start-time (bench-get-time))
+    (bench-mark-hanoi)
+;    (setq bench-mark-hanoi-times (cons (- (bench-get-time) start-time ) bench-mark-hanoi-times ))
+    (setq times (- times 1))))
+)
+
+(defun bench-mark-hanoi ()
+  "How long to complete the tower of hanoi."
+  (hanoi 4))
+
+;-----------------------------------------------------------------------------
+(defvar bench-mark-font-lock-buffer nil "buffer used for bench-mark-fontlock")
+
+(defun bench-handler-font-lock (times)
+  (setq bench-mark-font-lock-buffer (find-file bench-lisp-file))
+  (while (> times 0)
+    (bench-mark-font-lock)
+    (font-lock-mode)			; Turn it off
+    (setq times (- times 1)))
+  (kill-buffer bench-mark-font-lock-buffer)
+)
+
+(defun bench-mark-font-lock ()
+  "How long to fonitfy a large file."
+  (font-lock-fontify-buffer)
+)
+
+;-----------------------------------------------------------------------------
+(defvar bench-mark-scrolling-buffer nil "buffer used for bench-mark-scrolling")
+
+(defun bench-handler-scrolling (times)
+  (setq bench-mark-scrolling-buffer (find-file bench-lisp-file))
+  (set-buffer bench-mark-scrolling-buffer)
+;  (setq scroll-step 1)
+  (font-lock-mode -1)
+  (goto-char (point-min))		;Start at point min
+  (let ((temp-times times))
+    (while (> temp-times 0)
+      (bench-mark-scrolling-down)
+      (bench-mark-scrolling-up)
+      (setq temp-times (- temp-times 1))))
+
+  (font-lock-fontify-buffer)
+
+  (goto-char (point-min))		;Start at point min
+  (let ((temp-times times))
+    (while (> temp-times 0)
+      (bench-mark-scrolling-down-fontified)
+      (bench-mark-scrolling-up-fontified)
+      (setq temp-times (- temp-times 1))))
+  (kill-buffer bench-mark-scrolling-buffer)
+)
+
+(defun bench-mark-scrolling-down ()
+  "How long does it take to scroll down through a large file.
+Expect point to be at point min"
+  (let ((buffer-read-only t))
+    (while (< (point) (point-max))
+      (next-line 1)
+      (sit-for 0))))
 
-(defconst bench-version 1.0)
+(defun bench-mark-scrolling-up ()
+  "How long does it take to scroll up through a large fontified ile."
+  (let ((buffer-read-only t))
+    (while (> (point) (point-min))
+      (previous-line 1)
+      (sit-for 0))))
+
+(defun bench-mark-scrolling-down-fontified ()
+  "How long does it take to scroll down through a large fontified file."
+  (let ((buffer-read-only t))
+    (goto-char (point-min))
+    (while (< (point) (point-max))
+      (next-line 1)
+      (sit-for 0))))
+
+(defun bench-mark-scrolling-up-fontified ()
+  "How long does it take to scroll up through a large fontified ile."
+  (let ((buffer-read-only t))
+    (while (> (point) (point-min))
+      (previous-line 1)
+      (sit-for 0))))
+
+;-----------------------------------------------------------------------------
+
+(defun bench-handler-make-frames (times)
+  (let ((temp-times times)
+	(frame))
+    (while (> temp-times 0)
+      (setq frame (bench-mark-make-frame)) ;Make frame
+      (bench-mark-delete-frame frame)	;Delete frame
+      (setq temp-times (- temp-times 1))))
+
+  (let ((temp-times times)
+	(frames))
+    (while (> temp-times 0)
+      (setq frames (cons (bench-mark-make-multiple-frames) frames)) ;Make frames
+      (setq temp-times (- temp-times 1)))
+
+    (setq temp-times times)
+
+    (while (> temp-times 0)
+      (bench-mark-delete-multiple-frames (car frames))	;Delete frames
+      (setq frames (cdr frames))
+      (setq temp-times (- temp-times 1))))
+
+)
+
+(defun bench-mark-make-frame ()
+  "How quickly can emacs create a new frame."
+  (make-frame))
+
+(defun bench-mark-delete-frame (frame)
+  "How quickly can emacs create a new frame."
+  (delete-frame frame))
+
+(defun bench-mark-make-multiple-frames ()
+  "How quickly can emacs create a new frame."
+  (make-frame))
+
+(defun bench-mark-delete-multiple-frames (frame)
+  "How quickly can emacs create a new frame."
+  (delete-frame frame))
+
+
+;-----------------------------------------------------------------------------
+(defconst bench-mark-make-words-buffer nil)
+(defconst bench-mark-make-words-buffer-name "*bench-mark-make-words*")
+(defconst bench-mark-make-words-number-of-words 10000)
+
+(defun bench-handler-make-words (times)
+  (setq bench-mark-make-words-buffer (get-buffer-create bench-mark-make-words-buffer-name))
+  (set-buffer bench-mark-make-words-buffer)
+  (while (> times 0)
+    (bench-mark-make-words)
+    (erase-buffer)
+    (setq times (- times 1)))
+  (kill-buffer bench-mark-make-words-buffer)
+)
 
-(defconst bench-large-lisp-file "/usr/local/lib/gnus-bench.el"
-  "Large lisp file to use in benchmarks.
-Grab `ftp://ftp.xemacs.org/pub/beta/contrib/gnus-bench.el.gz' for a good
-version.  Don't install this file with Emacs/XEmacs.")
+(defun bench-mark-make-words ()
+  "How long does it take to generate lots of random words."
+  (let ((tmp-words bench-mark-make-words-number-of-words))
+    (while (not (= tmp-words 0))
+      (let ((word-len (random 10)))
+	(while (not (= word-len 0))
+	  (insert (+ ?a (random 25)))
+	  (setq word-len (- word-len 1))))
+      (insert "\n")
+      (setq tmp-words (- tmp-words 1)))))
+
+;-----------------------------------------------------------------------------
+(defconst bench-mark-sort-words-buffer-name "*bench-mark-sort-words*")
+(defconst bench-mark-sort-words-buffer nil)
+(defconst bench-mark-sort-words-number-words 10000)
+
+(defun bench-handler-sort-words (times)
+  (setq bench-mark-sort-words-buffer (get-buffer-create bench-mark-sort-words-buffer-name))
+  (switch-to-buffer bench-mark-sort-words-buffer)
+  (while (> times 0)
+    (bench-pre-sort-words)			;Generate the random words
+    (bench-mark-sort-words)			;Sort those puppies
+    (erase-buffer)
+    (setq times (- times 1)))
+  (kill-buffer bench-mark-sort-words-buffer)
+)
+
+(defun bench-pre-sort-words ()
+  "How long does it take to generate lots of random words."
+  (let ((tmp-words bench-mark-sort-words-number-words))
+    (while (not (= tmp-words 0))
+      (let ((word-len (random 10)))
+	(while (not (= word-len 0))
+	  (insert (+ ?a (random 25)))
+	  (setq word-len (- word-len 1))))
+      (insert "\n")
+      (setq tmp-words (- tmp-words 1)))))
+
+(defun bench-mark-sort-words ()
+  (sort-lines nil (point-min) (point-max))
+)
+
+;-----------------------------------------------------------------------------
+; Byte compile a file
+(defun bench-handler-byte-compile (times)
+  (while (> times 0)
+    (bench-mark-byte-compile)
+    (setq times (- times 1)))
+)
+
+(defun bench-mark-byte-compile ()
+  "How long does it take to byte-compile a large lisp file"
+  (byte-compile-file bench-lisp-file)
+)
+
+;-----------------------------------------------------------------------------
+; Run through a loop
+
+(defconst bench-mark-loop-count 250000)
+
+(defun bench-handler-loop (times)
+  (while (> times 0)
+    (bench-mark-loop)
+    (setq times (- times 1)))
+)
+
+(defun bench-mark-loop ()
+  "How long does it take to run through a loop."
+  (let ((count bench-mark-loop-count))
+    (let ((i 0) (gcount 0))
+      (while (< i count)
+	(increment)
+	(setq i (1+ i)))
+      (message "gcount = %d" gcount))))
+
+(defun increment ()
+  "Increment a variable for bench-mark-loop."
+  (setq gcount (1+ gcount)))
 
-(defconst bench-sort-buffer "*Sort*"
-  "File to be used in the sort benchmark")
+;-----------------------------------------------------------------------------
+(defconst bench-mark-large-list-list-size 500000
+  "Size of list to use in small list creation/garbage collection")
+(defconst bench-mark-large-list-num-lists 10)
+
+(defun bench-handler-large-list (times)
+  (let ((tmp-foo bench-mark-large-list-num-lists))
+    (while (> tmp-foo 0)
+      (bench-mark-large-list)
+      (setq tmp-foo (- tmp-foo 1))))
+)
+
+(defun bench-mark-large-list ()
+  (make-list bench-mark-large-list-list-size '1)
+)
+
+;-----------------------------------------------------------------------------
+(defun bench-mark-large-list-garbage-collect (times)
+  (garbage-collect)
+)
+
+;-----------------------------------------------------------------------------
+(defconst bench-mark-small-list-list-size 10
+  "Size of list to use in small list creation/garbage collection")
+
+(defconst bench-mark-small-list-num-lists 100000
+  "Number of lists to use in small list creation/garbage collections")
+
+(defun bench-handler-small-list (times)
+  (let ((tmp-foo bench-mark-small-list-num-lists))
+    (while (> tmp-foo 0)
+      (bench-mark-small-list)
+      (setq tmp-foo (- tmp-foo 1)))
+))
+
+(defun bench-mark-small-list ()
+  (make-list bench-mark-small-list-list-size '1)
+)
 
-(defconst bench-sort-number-words 10000
-  "Number of words to use in sort benchmark")
+;-----------------------------------------------------------------------------
+(defun bench-mark-small-list-garbage-collect (times)
+  (garbage-collect)
+)
+
+;-----------------------------------------------------------------------------
+(defconst bench-mark-insert-into-empty-buffer-num-words 100000)
+
+(defun bench-handler-insert-into-empty-buffer ()
+  (set-buffer (get-buffer-create "*tmp*"))
+  (bench-mark-insert-into-empty-buffer)
+  (erase-buffer)
+  (kill-buffer "*tmp*")
+)
+
+(defun bench-mark-insert-into-empty-buffer ()
+  (let ((a bench-mark-insert-into-empty-buffer-num-words))
+    (while (> a 0)
+      (insert "0123456789\n")
+      (setq a (1- a))))
+)
+
+;=============================================================================
+(defconst bench-version (let ((rcsvers "$Revision: 1.2 $"))
+			  (substring rcsvers 11 (- (length rcsvers) 2)))
+  "*Version number of bench.el")
+
+(defconst temp-dir (file-name-as-directory
+		    (or (getenv "TMPDIR")
+			(getenv "TMP")
+			(getenv "TEMP")
+			"/tmp/")))
+
+(defconst bench-large-lisp-file (concat temp-dir "./bench-large.el")
+  "Large lisp file to use in benchmarks should be /temp-dir/bench-text.el")
+
+(defconst bench-small-lisp-file (concat temp-dir "./bench-small.el")
+  "Large lisp file to use in benchmarks should be /temp-dir/bench-text.el")
+
+(defconst bench-lisp-file bench-large-lisp-file)
 
 (defconst bench-pre-bench-hook nil
   "Hook for individual bench mark initialization.")
@@ -59,19 +366,19 @@
 
 (defconst bench-mark-function-alist 
   '(
-    (bench-mark-1 . "Tower of Hanoi")
-    (bench-mark-2 . "Font Lock")
-    (bench-mark-3 . "Large File scrolling")
-    (bench-mark-4 . "Frame Creation")
-    (bench-mark-5 . "Generate Words")
-    (bench-mark-6 . "Sort Buffer")
-    (bench-mark-7 . "Large File bytecompilation")
-    (bench-mark-8 . "Loop Computation")
-    (bench-mark-9 . "Make a Few Large Size List")
-    (bench-mark-10 . "Garbage Collection Large Size List")
-    (bench-mark-11 . "Make Several Small Size List")
-    (bench-mark-12 . "Garbage Collection Small Size List")
-    (bench-mark-13 . "Append to buffer")
+    (bench-handler-hanoi . "Tower of Hanoi")
+    (bench-handler-font-lock               . "Font Lock")
+    (bench-handler-scrolling               . "Large File scrolling")
+    (bench-handler-make-frames             . "Frame Creation")
+    (bench-handler-make-words              . "Generate Words")
+    (bench-handler-sort-words              . "Sort Buffer")
+    (bench-handler-byte-compile            . "Large File bytecompilation")
+    (bench-handler-loop                    . "Loop Computation")
+    (bench-handler-large-list              . "Make a Few Large Size List")
+    (bench-mark-large-list-garbage-collect . "Garbage Collection Large Size List")
+    (bench-handler-small-list              . "Make Several Small Size List")
+    (bench-mark-small-list-garbage-collect  . "Garbage Collection Small Size List")
+    (bench-handler-insert-into-empty-buffer . "Text Insertion")
 ))
 
 (defconst bench-enabled-profiling nil
@@ -82,126 +389,18 @@
 
 (setq gc-cons-threshold 40000000)
 
-(defconst bench-number-of-large-lists 10
-  "Number of lists to use in large list creation/garbage collections")
-
-(defconst bench-number-of-small-lists 1000000
-  "Number of lists to use in small list creation/garbage collections")
-
-(defconst bench-large-list-size 1000000
-  "Size of list to use in small list creation/garbage collection")
-
-(defconst bench-small-list-size 10
-  "Size of list to use in small list creation/garbage collection")
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-1 ()
-  "How long to complete the tower of hanoi."
-  (hanoi 4))
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-2 ()
-  "How long to fonitfy a large file."
-  (find-file bench-large-lisp-file)
-  (font-lock-fontify-buffer))
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-3 ()
-  "How long does it take to scroll down through a large file."
-  (let ((buffer-read-only t))
-    (goto-char (point-min))
-    (while (< (point) (point-max))
-      (next-line 1)
-      (sit-for 0))))
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-4 ()
-  "How quickly can emacs create a new frame."
-  (make-frame))
-
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-5 ()
-  "How long does it take to generate lots of random words."
-  (set-buffer (get-buffer-create bench-sort-buffer))
-  (let ((tmp-words bench-sort-number-words))
-    (while (not (= tmp-words 0))
-      (let ((word-len (random 10)))
-	(while (not (= word-len 0))
-	  (insert (+ ?a (random 25)))
-	  (setq word-len (- word-len 1))))
-      (insert "\n")
-      (setq tmp-words (- tmp-words 1)))))
-
-;-----------------------------------------------------------------------------
-
-(defun bench-mark-6 ()
-  "How long does it take to sort the random words from bench-mark-5."
-  (set-buffer (get-buffer-create bench-sort-buffer))
-  (sort-lines nil (point-min) (point-max))
-)
+(defconst bench-small-frame-alist '((height . 24) (width . 80)))
+(defconst bench-medium-frame-alist '((height . 48) (width . 80)))
+(defconst bench-large-frame-alist '((height . 72) (width . 80)))
 
-;-----------------------------------------------------------------------------
-(defun bench-mark-7 ()
-  "How long does it take to byte-compile a large lisp file"
-  (byte-compile-file bench-large-lisp-file)
-)
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-8 ()
-  "How long does it take to run through a loop."
-  (let ((count 250000))
-    (let ((i 0) (gcount 0))
-      (while (< i count)
-	(increment)
-	(setq i (1+ i)))
-      (message "gcount = %d" gcount))))
-
-(defun increment ()
-  "Increment a variable for bench-mark-8."
-  (setq gcount (1+ gcount)))
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-9 ()
-  (let ((tmp-foo bench-number-of-large-lists))
-    (while (> tmp-foo 0)
-      (make-list bench-large-list-size '1)
-      (setq tmp-foo (- tmp-foo 1)))
-      )
-)
+(defsubst bench-get-time ()
+  ;; Stolen from elp
+  ;; get current time in seconds and microseconds. I throw away the
+  ;; most significant 16 bits of seconds since I doubt we'll ever want
+  ;; to profile lisp on the order of 18 hours. See notes at top of file.
+  (let ((now (current-time)))
+    (+ (float (nth 1 now)) (/ (float (nth 2 now)) 1000000.0))))
 
-;-----------------------------------------------------------------------------
-(defun bench-mark-10 ()
-  (garbage-collect)
-)
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-11 ()
-  (let ((tmp-foo bench-number-of-small-lists))
-    (while (> tmp-foo 0)
-      (make-list bench-small-list-size '1)
-      (setq tmp-foo (- tmp-foo 1))
-      ))
-)
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-12 ()
-  (garbage-collect)
-)
-
-;-----------------------------------------------------------------------------
-(defun bench-mark-13 ()
-  (unwind-protect
-      (let ((a 100000))
-        (set-buffer (get-buffer-create "*tmp*"))
-        (erase-buffer)
-        (while (> a 0)
-          (insert "0123456789\n")
-          (setq a (1- a))))
-    (kill-buffer "*tmp*")))
-
-
-;=============================================================================
 (defun bench-init ()
   "Initialize profiling for bench marking package."
   (if (fboundp 'start-profiling)
@@ -210,9 +409,29 @@
 	(when (profiling-active-p)
 	  (stop-profiling)
 	  (clear-profiling-info)))
-    (message "Profiling not available in this Emacs.")
+    (message "Profiling not available in this XEmacs.")
     (sit-for 2)))
 
+(defun bench-test-init ()
+  "Initialize profiling for bench marking package."
+  (if (fboundp 'start-profiling)
+      (let ((buf (get-buffer-create bench-mark-profile-buffer)))
+	(erase-buffer buf)
+	(when (profiling-active-p)
+	  (stop-profiling)
+	  (clear-profiling-info)))
+    (message "Profiling not available in this XEmacs.")
+    (sit-for 2))
+  (setq bench-lisp-file bench-small-lisp-file)
+  (setq bench-mark-make-words-number-of-words 100)
+  (setq bench-mark-sort-words-number-of-words 100)
+  (setq bench-mark-loop-count 10000)
+  (setq bench-mark-large-list-list-size 500)
+  (setq bench-mark-small-list-num-lists 100)
+  (setq bench-mark-insert-into-empty-buffer-num-words 100)
+  
+)
+
 (defun bench-profile-start (test-name)
   "Turn on profiling for test `test-name'."
   (when (and bench-enabled-profiling
@@ -240,6 +459,16 @@
 (add-hook 'bench-pre-bench-hook 'bench-profile-start)
 (add-hook 'bench-post-bench-hook 'bench-profile-stop)
 
+(defun bench-post ()
+"Post processing of elp results"
+; I can't figure out a good way to sort the lines numerically.
+; If someone comes up with a good way, let me know.
+  (goto-char (point-min))
+  (next-line 2)
+  (sort-lines nil (point) (point-max))
+  (mail-results (current-buffer))
+)
+
 (defun bench (arg)
   "Run a series of benchmarks."
   (interactive "p")
@@ -248,35 +477,68 @@
   (bench-init)
   (if (fboundp 'byte-optimize)		;Turn off byte-compile optimization in XEmacs
       (setq byte-optimize nil))
+  (if (fboundp 'menu-bar-mode)
+      (menu-bar-mode -1))			;Turn off menu-bar
   (let ((benches bench-mark-function-alist))
     (while benches
       (let ((test-name (cdar benches)))
 	(run-hook-with-args 'bench-pre-bench-hook test-name)
-	(let ((count arg))
-	  (while (> count 0)
-	    (message "Running %s - %s." (symbol-name (caar benches)) test-name)
-	    (funcall (caar benches))
-	    (setq count (1- count))))
+	(message "Running %s - %s." (symbol-name (caar benches)) test-name)
+	(funcall (caar benches) arg)
 	(setq benches (cdr benches))
 	(run-hook-with-args 'bench-post-bench-hook test-name))
       ))
   (elp-results)
-  (goto-char (point-min))
-  (next-line 2)
-; I can't figure out a good way to sort the lines numerically.
-; If someone comes up with a good way, let me know.
-  (sort-lines nil (point) (point-max))
-  (goto-char (point-min))
+  (bench-post)
+)
+
+(defun bench-test (arg)
+  "Run all the tests but with smaller values so the tests run quicker.
+This way I don't have to sit around to see if the tests complete"
+  (interactive "p")
+  (elp-instrument-package "bench-mark") ;Only instrument functions
+                                        ;beginning with bench-mark
+  (bench-test-init)
+  (if (fboundp 'byte-optimize)		;Turn off byte-compile optimization in XEmacs
+      (setq byte-optimize nil))
+  (if (fboundp 'menu-bar-mode)
+      (menu-bar-mode -1))			;Turn off menu-bar
   (let ((benches bench-mark-function-alist))
     (while benches
-      (goto-char (point-min))
-      (let ((test-name (cdar benches))
-	    (test-func (caar benches)))
-	(search-forward (symbol-name test-func))
-	(end-of-line)
-	(insert "   <= " test-name))
+      (let ((test-name (cdar benches)))
+	(run-hook-with-args 'bench-pre-bench-hook test-name)
+	(message "Running %s - %s." (symbol-name (caar benches)) test-name)
+	(funcall (caar benches) arg)
 	(setq benches (cdr benches))
+	(run-hook-with-args 'bench-post-bench-hook test-name))
       ))
+  (elp-results)
+  (bench-post)
 )
 
+
+(defconst bench-send-results-to "holder@rsn.hp.com")
+(defconst bench-subject "Bench Mark Results")
+(defconst bench-system-form (format "
+
+Please fill in as much of the following as you can
+and then hit C-cC-c to send.
+
+CPU Manufacturer (Intel,HP,DEC,etc.): 
+CPU Type (Pentium,Alpha): 
+CPU Speed: 
+RAM (in meg): 
+Emacs Version: %s
+Emacs (version): %s
+Compile line:
+Bench Version: %s
+" emacs-version (emacs-version) bench-version))
+
+(defun mail-results (buffer)
+  (mail nil bench-send-results-to bench-subject)
+  (sit-for 0)
+  (goto-char (point-max))
+  (insert bench-system-form)
+  (insert-buffer buffer)
+)
 ;;; bench.el ends here