This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: consecutive 'let


Hi Yaroslav.  As far as I can tell there's no need to make this a
macro - you could do it with a function like so.

(define (time-process process)
   (let ((start-mem (blah-blah blah))
          (start-time (blah-blah)))
     (dynamic-wind ()

       (lambda ()
         (report-time-and-memory start-time start-mem))

       ;; run our process (a function)
       process

       (lambda ()
         (let ((end-mem (blah-blah blah))
               (end-time (blah-blah blah)))
           (report-duration-and-memory start-time end-time start-mem
end-mem)))))

The dynamic-wind ensures that you will report the time and memory
usage no matter what process does.

If you wanted to then simplify the syntax, you could wrap the function
in a simple macro that wraps the tested expression in a lambda.


(define-syntax time
  (syntax-rules ()
    ((time expression)
     ;; =>
     (time-process (lambda () expression)))))

That is, assuming the purpose is to measure a process' duration and
memory usage.

And assuming I'm not missing something - was there a reason one needs
to use a macro here?  I only like to use them to modify syntax; I try
not to include too much 'function' functionality in them, if only
because functions are more easily debugged (and reused).

I don't know the details of java's MemoryMXBean and MemoryUsage
though, so perhaps someone else can help with that.

- Jake

On Dec 26, 2007 10:36 AM, Yaroslav Kavenchuk <kavenchuk@jenty.by> wrote:
> In macro - analog CL's 'time:
>
> (define-syntax time
>  (syntax-rules ()
>    ((time expression)
>     (let ((mem-bean :: <java.lang.management.MemoryMXBean>
>            (java.lang.management.ManagementFactory:getMemoryMXBean)))
>       (mem-bean:gc) (mem-bean:gc) (mem-bean:gc) ;; Why? I do not know :)
>       (let ((begin-time :: <gnu.math.IntNum>
> (java.lang.System:currentTimeMillis))
>             (begin-non-heap-memo :: <java.lang.management.MemoryUsage>
> (mem-bean:getNonHeapMemoryUsage))
>             (begin-heap-memo :: <java.lang.management.MemoryUsage>
> (mem-bean:getHeapMemoryUsage))
>             (ret expression)
>             (end-heap-memo :: <java.lang.management.MemoryUsage>
> (mem-bean:getHeapMemoryUsage))
>             (end-non-heap-memo :: <java.lang.management.MemoryUsage>
> (mem-bean:getNonHeapMemoryUsage))
>             (end-time :: <gnu.math.IntNum>
> (java.lang.System:currentTimeMillis)))
>         (format #t "Value: ~A\n" ret)
>         (format #t "Duration: ~A sec.\n" (/ (- end-time begin-time)
> 1000.0))
>         (format #t "Memory usage:\n  Heap memory:\n")
>         (format #t "    init:      ~A\n" (- end-heap-memo:init
> begin-heap-memo:init))
>         (format #t "    used:      ~A\n" (- end-heap-memo:used
> begin-heap-memo:used))
>         (format #t "    committed: ~A\n" (- end-heap-memo:committed
> begin-heap-memo:committed))
>         (format #t "    max:       ~A\n" (- end-heap-memo:max
> begin-heap-memo:max))
>         (format #t "  Non heap memory:\n")
>         (format #t "    init:      ~A\n" (- end-non-heap-memo:init
> begin-non-heap-memo:init))
>         (format #t "    used:      ~A\n" (- end-non-heap-memo:used
> begin-non-heap-memo:used))
>         (format #t "    committed: ~A\n" (- end-non-heap-memo:committed
> begin-non-heap-memo:committed))
>         (format #t "    max:       ~A\n" (- end-non-heap-memo:max
> begin-non-heap-memo:max)))
>       (mem-bean:gc)))))
>
> I can rely on consistent second 'let? Or I should write so:
>
> (define-syntax time
>  (syntax-rules ()
>    ((time expression)
>     (let ((mem-bean :: <java.lang.management.MemoryMXBean>
>            (java.lang.management.ManagementFactory:getMemoryMXBean))
>           (begin-time :: <gnu.math.IntNum> 0)
>           (begin-non-heap-memo :: <java.lang.management.MemoryUsage>
> #!null)
>           (begin-heap-memo :: <java.lang.management.MemoryUsage> #!null)
>           (ret ())
>           (end-heap-memo :: <java.lang.management.MemoryUsage> #!null)
>           (end-non-heap-memo :: <java.lang.management.MemoryUsage> #!null)
>           (end-time :: <gnu.math.IntNum> 0))
>       (mem-bean:gc) (mem-bean:gc) (mem-bean:gc) ;; Why? I do not know :)
>       (set! begin-time (java.lang.System:currentTimeMillis))
>       (set! begin-non-heap-memo (mem-bean:getNonHeapMemoryUsage))
>       (set! begin-heap-memo (mem-bean:getHeapMemoryUsage))
>       (set! ret expression)
>       (set! end-heap-memo (mem-bean:getHeapMemoryUsage))
>       (set! end-non-heap-memo (mem-bean:getNonHeapMemoryUsage))
>       (set! end-time (java.lang.System:currentTimeMillis))
>       (format #t "Value: ~A\n" ret)
>       (format #t "Duration: ~A sec.\n" (/ (- end-time begin-time) 1000.0))
>       (format #t "Memory usage:\n  Heap memory:\n")
>       (format #t "    init:      ~A\n" (- end-heap-memo:init
> begin-heap-memo:init))
>       (format #t "    used:      ~A\n" (- end-heap-memo:used
> begin-heap-memo:used))
>       (format #t "    committed: ~A\n" (- end-heap-memo:committed
> begin-heap-memo:committed))
>       (format #t "    max:       ~A\n" (- end-heap-memo:max
> begin-heap-memo:max))
>       (format #t "  Non heap memory:\n")
>       (format #t "    init:      ~A\n" (- end-non-heap-memo:init
> begin-non-heap-memo:init))
>       (format #t "    used:      ~A\n" (- end-non-heap-memo:used
> begin-non-heap-memo:used))
>       (format #t "    committed: ~A\n" (- end-non-heap-memo:committed
> begin-non-heap-memo:committed))
>       (format #t "    max:       ~A\n" (- end-non-heap-memo:max
> begin-non-heap-memo:max))
>       (mem-bean:gc)))))
>
> And maybe I "invented the bicycle"? :)
>
> --
> WBR, Yaroslav Kavenchuk.
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]