hyrule icon indicating copy to clipboard operation
hyrule copied to clipboard

time-it macro

Open pyx opened this issue 7 years ago • 5 comments

As inspired by @gilch in discussion here: https://github.com/hylang/hy/pull/1179

The macro:

(defmacro/g! time-it [expr &optional setup round]
  `((fn []
      (do (import [timeit [timeit :as ~g!timeit]])
      ~(when setup setup)
      (defn testee [] ~expr)
      (setv kwargs {})
      ~(when round `(assoc kwargs "number" ~round))
      (apply ~g!timeit [testee] kwargs)))))
hy 0.11.0+353.gca6fd66 using CPython(default) 3.5.2 on Linux
=> (defmacro/g! time-it [expr &optional setup round]
...   `((fn []
...       (do (import [timeit [timeit :as ~g!timeit]])
...       ~(when setup setup)
...       (defn testee [] ~expr)
...       (setv kwargs {})
...       ~(when round `(assoc kwargs "number" ~round))
...       (apply ~g!timeit [testee] kwargs)))))
=> (time-it (inc 1))
0.6166748020004889
=> (time-it (inc anwser))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 1, in _hy_anon_fn_2
  File "/usr/lib64/python3.5/timeit.py", line 213, in timeit
    return Timer(stmt, setup, timer, globals).timeit(number)
  File "/usr/lib64/python3.5/timeit.py", line 178, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
  File "<input>", line 1, in testee
NameError: name 'anwser' is not defined
=> (time-it (inc answer) (do (print "thinking.." (setv answer 42))))
thinking.. 42
0.641465346001496
=> (time-it (inc a) (setv a 12) 100)
6.975599899305962e-05
=> (time-it (inc 1) () 100)
6.572400161530823e-05
=> (time-it (inc 1) :round 100)  ;; works by accident, :round by itself is a valid expression
6.490799933089875e-05

Another approach is using read-str

Caveat

I've been fighting the macro system for the last hour, as we cannot use &kwargs with defmacro, so unless we use &rest and parse the argument ourselves (I have a kind-of-working prototype, but it is so ugly that I do not dare to share), the form of the macro is a bit rigid, I skipped the timer argument for simplicity's sake, and right now, one have to pass in the setup code to specify the round of iteration, see above.

pyx avatar Dec 22 '16 03:12 pyx