Created
April 12, 2010 19:01
-
-
Save citizen428/363888 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user=> ; generate random number | |
user=> (rand) | |
0.8545074632292601 | |
user=> ; infinite list of random numbers | |
user=> ; make sure to set *print-length* | |
user=> (set! *print-length* 10) | |
10 | |
user=> (repeatedly rand) | |
(0.13569783475252373 0.585868618595554 0.7048671603900427 0.1440943435265447 0.24546858003727567 0.15406959135696596 0.41117257771529947 0.1115848319639422 0.669215744258339 0.1521494621978804 ...) | |
user=> ; get the reductions function from seq-utils | |
user=> (use '[clojure.contrib.seq-utils :only (reductions)]) | |
nil | |
user=> ; example output | |
user=> (reductions + (repeatedly rand)) | |
(0.41005883808810484 1.181004457271026 1.683921783958707 1.8089826384110315 2.665952641217805 3.1313294137408696 3.910840785170331 4.556861781354299 4.684333796200002 5.366467630925037 ...) | |
user=> ; take from this list while < 1 | |
user=> (take-while #(< % 1) (reductions + (repeatedly rand))) | |
(0.15208609594210099 0.5025764514682954) | |
user=> ; the next number got us over 1, so we have to add 1 to the count | |
user=> (+ 1 (count (take-while #(< % 1) (reductions + (repeatedly rand))))) | |
2 | |
user=> ; wrap it up in a function | |
user=> (defn numbers-added [] (+ 1 (count (take-while #(< % 1) (reductions + (repeatedly rand)))))) | |
#'user/numbers-added | |
user=> ; example usage | |
user=> (numbers-added) | |
3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user=> ; take n elements from infinite list created with other function | |
user=> (defn take-n [n func] (take n (repeatedly func))) | |
#'user/take-n | |
user=> ; example usage | |
user=> (take-n 5 numbers-added) | |
(4 2 2 3 3) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user=> ; the def-ed seq will be cached | |
user=> (def rands (repeatedly rand)) | |
#'user/rands | |
user=> rands | |
(0.6087015703728027 0.5133925986315239 0.6659904034658731 0.2585419462841031 0.46063953992700934 0.19370220942302052 0.15827993171228638 0.8614635645469774 0.6329769699781875 0.4159676205268511 ...) | |
user=> (take 5 rands) | |
(0.6087015703728027 0.5133925986315239 0.6659904034658731 0.2585419462841031 0.46063953992700934) | |
user=> (take 5 rands) | |
(0.6087015703728027 0.5133925986315239 0.6659904034658731 0.2585419462841031 0.46063953992700934) | |
user=> ; no caching | |
user=> (take-n 5 numbers-added) | |
(3 2 5 2 2) | |
user=> (take-n 5 numbers-added) | |
(2 3 2 3 4) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user=> ; calculate the average | |
user=> (defn average [xs] (/ (reduce + xs) (count xs))) | |
#'user/average | |
user=> ; example usage | |
user=> (average (take-n 10 numbers-added)) | |
14/5 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user=> (map (fn [n] (float (average (take-n n numbers-added)))) '(1000 10000 100000 1000000)) | |
(2.727 2.7095 2.71827 2.71801) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(use '[clojure.contrib.seq-utils :only (reductions)]) | |
(defn numbers-added | |
[] | |
(+ 1 (count (take-while #(< % 1) (reductions + (repeatedly rand)))))) | |
(defn take-n | |
[n func] | |
(take n (repeatedly func))) | |
(defn average | |
[xs] | |
(/ (reduce + xs) (count xs))) | |
(map (fn [n] (double (average (take-n n numbers-added)))) '(1000 10000 100000 1000000)) |
Are you sure that's not only because of the different set of random numbers being averaged out? Have you compared several runs of map vs. pmap?
I did, but it turns out you're right - the next batch, it turns out that was a total fluke. Sadly, pmap is only marginally faster.
Edit: excellent blog post, I had never heard of this "effect" before.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Have you tried using pmap on that last call? Not sure why, but it's closer to e.