Mercurial > rlm
diff src/rlm/function_utils.clj @ 1:8565803376a4
upgrading source to work with clojure 1.4
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 28 Feb 2012 13:26:34 -0600 |
parents | 78a630e650d2 |
children | b8bbb0dbda7b |
line wrap: on
line diff
1.1 --- a/src/rlm/function_utils.clj Tue Oct 18 00:57:08 2011 -0700 1.2 +++ b/src/rlm/function_utils.clj Tue Feb 28 13:26:34 2012 -0600 1.3 @@ -4,67 +4,10 @@ 1.4 (ns 1.5 rlm.function-utils 1.6 "Collection of Operators on Pure Functions" 1.7 - {:author "Robert McIntyre"} 1.8 - (:use [clojure.contrib.profile])) 1.9 + {:author "Robert McIntyre"}) 1.10 1.11 (def void ::void) 1.12 1.13 -(comment 1.14 - 1.15 - "Please help me out here. I'm trying to make a higher order function that takes 1.16 - pure functions that are mathmaticaly the same but have different times and returns another 1.17 - function that runs them both and returns the resut of the one that finishes first." 1.18 - 1.19 - 1.20 - "here's a repl session: 1.21 - 1.22 -mobius> " (time (dotimes [_ 500]((mix-futures + +) 40 3 3 3 3 3))) " 1.23 -Elapsed time: 85.792995 msecs 1.24 -nil 1.25 -mobius> " (time (dotimes [_ 500](+ 40 3 3 3 3 3))) " 1.26 -Elapsed time: 6.956338 msecs 1.27 -nil 1.28 -mobius> " (time (dotimes [_ 500]((mix-threads + +) 40 3 3 3 3 3))) " 1.29 -Elapsed time: 706.227065 msecs 1.30 -nil 1.31 - 1.32 - 1.33 -mobius> " (defn fast-five [& args] 5) " 1.34 -#'mobius/fast-five 1.35 - 1.36 -mobius> " (defn slow-five [& args] (Thread/sleep 5000) (println "Oh YEAH!!!!") 5) " 1.37 -#'mobius/slow-five 1.38 - 1.39 -mobius> " (profile (time (dotimes [_ 5000] (thread-five)))) " 1.40 -\"Elapsed time: 12187.981587 msecs\" 1.41 - Name mean min max count sum 1.42 - create-atom 9621 2025 4433928 5000 48106830 1.43 -create-threads 5156 2724 2880268 5000 25783796 1.44 - kill-threads 91313 27866 11175718 5000 456567066 1.45 - loop 2124249 38482 18470781 5000 10621249899 1.46 - return 1242 838 5309 5000 6212626 1.47 - start-threads 252985 110348 12272835 5000 1264927953 1.48 -nil 1.49 - 1.50 -mobius> " (profile (time (dotimes [_ 5000] (future-five)))) " 1.51 -\"Elapsed time: 607.266671 msecs\" 1.52 - Name mean min max count sum 1.53 - create-atom 1472 1047 31708 5000 7363139 1.54 -create-futures 30539 2514 1330660 5000 152697998 1.55 - kill-threads 54158 2444 3938833 5000 270792897 1.56 - loop 81117 8800 6083059 5000 405587516 1.57 - return 1215 838 618782 5000 6078146 1.58 -nil 1.59 - 1.60 - 1.61 - 1.62 -What can I improve here, and why is the future version sooo much faster than the 1.63 -thread version? Is there a better way than using loop? 1.64 -" 1.65 - 1.66 -) 1.67 - 1.68 - 1.69 (defn mix 1.70 "Takes any number of mathematically equal functions with 1.71 possibly different run-times and returns a function that 1.72 @@ -80,44 +23,40 @@ 1.73 (dorun (map future-cancel futures)) 1.74 answer)))) 1.75 1.76 +;; (defn mix-threads 1.77 +;; " Takes any number of pure functions that take the same arguments and 1.78 +;; compute the same value and returns a function that runs each in a separate 1.79 +;; thread, returns the result from the first thread which finshes, and cancels 1.80 +;; the other threads. Explicitly uses nasty Threads. 1.81 1.82 - 1.83 - 1.84 -(defn mix-threads 1.85 - " Takes any number of pure functions that take the same arguments and 1.86 - compute the same value and returns a function that runs each in a separate 1.87 - thread, returns the result from the first thread which finshes, and cancels 1.88 - the other threads. Explicitly uses nasty Threads. 1.89 - 1.90 - For example: 1.91 - (do 1.92 - (defn fun1 [] (Thread/sleep 5000) 5) 1.93 - (defn fun2 [] (Thread/sleep 700000) 5) 1.94 - (time ((mix fun1 fun2)))) 1.95 +;; For example: 1.96 +;; (do 1.97 +;; (defn fun1 [] (Thread/sleep 5000) 5) 1.98 +;; (defn fun2 [] (Thread/sleep 700000) 5) 1.99 +;; (time ((mix fun1 fun2)))) 1.100 1.101 - Returns: 1.102 - | Elapsed time: 5000.66214 msecs 1.103 - 5" 1.104 - [& functions] 1.105 - (fn [& args] 1.106 - (let [result (prof :create-atom (atom void)) 1.107 - threads 1.108 - (prof :create-threads (map 1.109 - (fn [fun] 1.110 - (Thread. 1.111 - (fn [] 1.112 - (try (let [answer (apply fun args)] 1.113 - (reset! result answer)) 1.114 - (catch Exception _ nil))))) 1.115 - functions))] 1.116 +;; Returns: 1.117 +;; | Elapsed time: 5000.66214 msecs 1.118 +;; 5" 1.119 +;; [& functions] 1.120 +;; (fn [& args] 1.121 +;; (let [result (prof :create-atom (atom void)) 1.122 +;; threads 1.123 +;; (prof :create-threads (map 1.124 +;; (fn [fun] 1.125 +;; (Thread. 1.126 +;; (fn [] 1.127 +;; (try (let [answer (apply fun args)] 1.128 +;; (reset! result answer)) 1.129 +;; (catch Exception _ nil))))) 1.130 +;; functions))] 1.131 1.132 - (prof :start-threads (dorun (map #(.start %) threads))) 1.133 - (prof :loop (loop [] 1.134 - (if (= (deref result) void) 1.135 - (recur) 1.136 - (do (prof :kill-threads (dorun (map #(.stop %) threads))) 1.137 - (prof :return (deref result))) 1.138 - )))))) 1.139 +;; (prof :start-threads (dorun (map #(.start %) threads))) 1.140 +;; (prof :loop (loop [] 1.141 +;; (if (= (deref result) void) 1.142 +;; (recur) 1.143 +;; (do (prof :kill-threads (dorun (map #(.stop %) threads))) 1.144 +;; (prof :return (deref result))))))))) 1.145 1.146 (defmacro defmix 1.147 " Defines a function from any number of pure functions that take the same 1.148 @@ -148,10 +87,11 @@ 1.149 (let [doc-string (if (string? (first functions)) (first functions) "") 1.150 functions (if (string? (first functions)) (rest functions) functions) 1.151 arglists (:arglists (meta (resolve (eval `(quote ~(first functions)))))) 1.152 - name (with-meta name (assoc (meta name) :arglists `(quote ~arglists) :doc doc-string))] 1.153 + name (with-meta name 1.154 + (assoc (meta name) :arglists `(quote ~arglists) 1.155 + :doc doc-string))] 1.156 `(def ~name (mix ~@functions)))) 1.157 1.158 - 1.159 (defn runonce 1.160 "Decorator. returns a function which will run only once. Inspired 1.161 by Halloway's version from lancet." 1.162 @@ -165,21 +105,3 @@ 1.163 (reset! result (apply function args)) 1.164 @result))))) 1.165 1.166 - 1.167 - 1.168 -;I'm thinking this will be the docstring for mix eventually. 1.169 - 1.170 - ;; " Takes any number of pure functions that take the same arguments and 1.171 - ;; compute the same value and returns a function that runs each in a separate 1.172 - ;; thread, returns the result from the first thread which finshes, and cancels 1.173 - ;; the other threads. 1.174 - 1.175 - ;; For example: 1.176 - ;; (do 1.177 - ;; (defn fun1 [] (Thread/sleep 5000) 5) 1.178 - ;; (defn fun2 [] (Thread/sleep 700000) 5) 1.179 - ;; (time ((mix fun1 fun2)))) 1.180 - 1.181 - ;; Returns: 1.182 - ;; | Elapsed time: 5000.66214 msecs 1.183 - ;; 5"