tttime added by megane on Sat Aug 25 16:26:01 2018

(define *tttime-stack* #f)
(import (only (chicken process) process-sleep)
        (chicken base)
        (only (chicken time) current-milliseconds)
        (only (chicken format) printf format))
(define (report-tttime!)
  (define (tots s)
    (if (null? (caddr s))
        (list (cadr s))
        (cons (apply + (map cadr (caddr s)))
              (map tots (caddr s)))))

  (define (P s t ind)
    (let* ([t1 (cadr s)]
           [t2 (car t)]
           [td (- t1 t2)])
      (printf "~a~a: ~ams~a\n"
              ind (car s) t1
              (if (and (not (null? (cdr t))) (<= .1 td))
                  (format " (~ams hidden)" td)
                  "")))
    (for-each (cute P <> <> (string-append "  " ind))
              (caddr s)
              (cdr t)))

  (define (rev s)
    (list (car s) (cadr s) (reverse (map rev (caddr s)))))

  (let ([stack (rev *tttime-stack*)])
    (P stack (tots stack) ""))
  (set! *tttime-stack* #f))

(define-syntax tttime
  (ir-macro-transformer
   (lambda (e inj cmp)
     (apply
      (lambda (name . body)
	`(let ([stack *tttime-stack*]
               [_ (set! *tttime-stack* '())]
               [start-t (current-milliseconds)])
	   (receive r (begin ,@body)
             (let ([e (list ,name (- (current-milliseconds) start-t) *tttime-stack*)])
	       (if stack
		   (set! *tttime-stack* (cons e stack))
		   (begin
		     (set! *tttime-stack* e)
		     (report-tttime!))))
	     (apply values r))))
      (cdr e)))))

(receive v (tttime "total"
                   (values (tttime "do this" (+ (tttime "1" 1)
                                          (begin (sleep 1) 2)
                                          (tttime "2" (sleep 1) 2)))
                           (tttime "do that"
                                   (+ (tttime "3" 3)
                                      (tttime "2" 2)))))
  (print v))