Patrick
Patrick

Reputation: 66

Extracting and writing the execution time of a function in clojure

I am trying to extract and write the execution time of a function in clojure but because of my lack of experience in clojure I'm not able to figure it out. Is there a way of that being done? If possible some code example would be perfect. Below is an example of the method that I am calling. Thanks.

(dotimes [i 3]
  (with-open [rdr (reader (str "") )]
    (doseq [line (line-seq rdr)]
      (display-huffman-encode line))))

Upvotes: 2

Views: 1989

Answers (2)

DarrylG
DarrylG

Reputation: 17156

Method 1: Use time macro. (time exp) is normally used to time functions, but it writes to elapsed time to standard out rather than to a file. You can use "write-out-str" to capture what is sent to standard output and write the result to a file (using "spit"). This solutions is (appends to file "times.txt"):

(use 'clojure.java.io)
(dotimes [i 3]
  (with-open [rdr (reader "input.txt")]
    (doseq [line (line-seq rdr)]
      (spit "times.txt" (with-out-str (time (display-huffman-encode line))) :append true))))

Method 2: Build your own macro that runs a function and returns the elapsed time. The returned result could then be written to a file. This solution is shown below ("bench" is the timing routine and I added separate functions for logging and display-huffman-encode).

(use 'clojure.java.io)
(defn log-info
  " Places a newline so every time is on a different line "
  [file-name s]
  (spit file-name (format "%s %n" (str s)) :append true)) ; %n places
                                 ; platform independent newline after each time

(defmacro bench
  " Times the execution of your function,
    discarding the output and returning the elapsed time in seconds
    (you can modify this by changing the divisor from 1e9 (i.e. for milliseconds it would be 1e6."
  ([& forms]
   `(let [start# (System/nanoTime)]
      ~@forms
      (double (/ (- (System/nanoTime) start#) 1e9)))))   ; Time in seconds

(defn display-huffman-encode  [x]
  " Test example of your display function--just sleeps for 100 ms each time its called to simulate processing "
  (Thread/sleep 100))   ; Sleeps 100 ms

; Example code using the above elements
; Reading and writing to the working directory with input from "input.txt" and logging output times to "times.txt" as the logged times
(dotimes [i 3]
  (with-open [rdr (reader "input.txt")]
    (doseq [line (line-seq rdr)]
  (log-info "times.txt" (bench (display-huffman-encode line))))))

Upvotes: 1

Petr Volny
Petr Volny

Reputation: 559

For measuring execution time of an expression you can use (time exp) (check out https://clojuredocs.org/clojure.core/time). It prints to stdout so I guess you can just evaluate your function wrapped in time in some loop and save the output to a file afterwards.

Upvotes: 1

Related Questions