~ chicken-core (chicken-5) a68c580475ded09cc716e5777a2a63cc29ba26ec
commit a68c580475ded09cc716e5777a2a63cc29ba26ec
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Sat Jan 2 17:24:37 2016 +0100
Commit: Evan Hanson <evhan@foldling.org>
CommitDate: Sat Jan 16 19:23:11 2016 +1300
Fix statistical percentage chicken-profile output
Now both profiling types write a header in the first line to indicate
the type of file, so that chicken-profiles knows whether to take the
highest or the total of the run time as 100% when dividing.
Signed-off-by: Evan Hanson <evhan@foldling.org>
diff --git a/chicken-profile.scm b/chicken-profile.scm
index 61ec0050..7e70236f 100644
--- a/chicken-profile.scm
+++ b/chicken-profile.scm
@@ -159,8 +159,10 @@ EOF
(make-vector symbol-table-size '()))
(define (read-profile)
- (let ((hash (make-symbol-table)))
- (do ((line (read) (read)))
+ (let* ((hash (make-symbol-table))
+ (header (read))
+ (type (if (symbol? header) header 'instrumented)))
+ (do ((line (if (symbol? header) (read) header) (read)))
((eof-object? line))
(##sys#hash-table-set!
hash (first line)
@@ -172,7 +174,7 @@ EOF
(lambda (sym counts)
(set! alist (alist-cons sym counts alist)))
hash)
- alist)))
+ (cons type alist))))
(define (format-string str cols #!optional right (padc #\space))
(let* ((len (string-length str))
@@ -195,17 +197,26 @@ EOF
(define (write-profile)
(print "reading `" file "' ...\n")
- (let* ((data0 (with-input-from-file file read-profile))
- (max-t (foldl (lambda (r t) (max r (third t))) 0 data0))
+ (let* ((type&data0 (with-input-from-file file read-profile))
+ (type (car type&data0))
+ (data0 (cdr type&data0))
+ ;; Instrumented profiling results in total runtime being
+ ;; counted for the outermost "main" procedure, while
+ ;; statistical counts time spent only inside the procedure
+ ;; itself. Ideally we'd have both, but that's tricky to do.
+ (total-t (foldl (if (eq? type 'instrumented)
+ (lambda (r t) (max r (third t)))
+ (lambda (r t) (+ r (third t))))
+ 0 data0))
(data (sort (map
(lambda (t)
(append
t
(let ((c (second t)) ; count
- (t (third t))) ; total time
+ (t (third t))) ; time tallied to procedure
(list (or (and c (> c 0) (/ t c)) ; time / count
0)
- (or (and (> max-t 0) (* (/ t max-t) 100)) ; % of max-time
+ (or (and (> total-t 0) (* (/ t total-t) 100)) ; % of total-time
0)
))))
data0)
diff --git a/profiler.scm b/profiler.scm
index 621f4ed4..f39f807d 100644
--- a/profiler.scm
+++ b/profiler.scm
@@ -37,6 +37,10 @@
(define-constant profile-info-entry-size 5)
+(define empty-file?
+ (foreign-lambda* bool ((scheme-object p))
+ "C_return(ftell(C_port_file(p)) == 0);"))
+
;;; Globals:
@@ -122,7 +126,10 @@
(##sys#print "[debug] writing profile...\n" #f ##sys#standard-error) )
(apply
with-output-to-file ##sys#profile-name
- (lambda ()
+ (lambda ()
+ (when (empty-file? (current-output-port)) ; header needed?
+ (write 'instrumented)
+ (write-char #\newline))
(for-each
(lambda (vec)
(let ([len (##sys#size vec)])
diff --git a/runtime.c b/runtime.c
index 460c0cfc..b4ab27ed 100644
--- a/runtime.c
+++ b/runtime.c
@@ -13234,6 +13234,7 @@ C_word C_i_dump_statistical_profile()
if (fp == NULL)
panic(C_text("could not write profile!"));
+ C_fputs(C_text("statistical\n"), fp);
for(n = 0; n < PROFILE_TABLE_SIZE; ++n) {
for(b = bp[ n ]; b != NULL; b = b2) {
b2 = b->next;
Trap