<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A Humble Programmer &#187; clojure</title>
	<atom:link href="http://hjiang.net/archives/tag/clojure/feed" rel="self" type="application/rss+xml" />
	<link>http://hjiang.net</link>
	<description>Notes on life, computing, and programming</description>
	<lastBuildDate>Wed, 21 Jul 2010 03:36:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Nonintrusive concurrency with Clojure</title>
		<link>http://hjiang.net/archives/365</link>
		<comments>http://hjiang.net/archives/365#comments</comments>
		<pubDate>Sat, 12 Dec 2009 01:49:51 +0000</pubDate>
		<dc:creator>j</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://hjiang.net/?p=365</guid>
		<description><![CDATA[最近对Clojure比较感兴趣，写了一个quick sort做测试。 单线程版： (defn qsort-seq [seq] (if (&#60;= (.length seq) 25) (selection-sort seq) (let [[first-half second-half] (qsort-partition seq 0) sorted-first-half (qsort-seq first-half) sorted-second-half (qsort-seq second-half)] (concat sorted-first-half sorted-second-half)))) 多线程版： (defn qsort [seq] (if (&#60;= (.length seq) 25) (selection-sort seq) (let [[first-half second-half] (qsort-partition seq 0) sorted-first-half (future (qsort first-half)) sorted-second-half (qsort second-half)] (concat @sorted-first-half sorted-second-half)))) [...]]]></description>
			<content:encoded><![CDATA[<p>最近对Clojure比较感兴趣，写了一个quick sort做测试。</p>

<p>单线程版：</p>

<pre><code>(defn qsort-seq [seq]
  (if (&lt;= (.length seq) 25)
    (selection-sort seq)
    (let [[first-half second-half] (qsort-partition seq 0)
          sorted-first-half (qsort-seq first-half)
          sorted-second-half (qsort-seq second-half)]
          (concat sorted-first-half sorted-second-half))))
</code></pre>

<p>多线程版：</p>

<pre><code>(defn qsort [seq]
  (if (&lt;= (.length seq) 25)
    (selection-sort seq)
    (let [[first-half second-half] (qsort-partition seq 0)
      sorted-first-half (future (qsort first-half))
      sorted-second-half (qsort second-half)]
      (concat @sorted-first-half sorted-second-half))))
</code></pre>

<p>可以看到两个版本基本是一样的，所以在Clojure里通常可以很快把单线程的程序并行化。下面是一些调用到的函数：</p>

<pre><code>(def random (new java.util.Random))

(defn gen_rand_ints [n]
  (loop [result [], i n]
    (if (zero? i)
      result
      (recur (conj result (.nextInt random)) (dec i)))))

(def values (vec (gen_rand_ints 10000)))

(defn swap [vec i j]
  (let [iv (vec i),
    jv (vec j)]
    (assoc vec i jv j iv)))

(defn selection-sort [seq]
  (defn index_of_smaller [seq i j]
    (if (&lt; (seq i) (seq j)) i j))
  (loop [seq- seq start 0]
    (if (&lt; start (.length seq))
      (let [index_of_smallest_v
            (reduce (partial index_of_smaller seq-)
                    (range start (.length seq-)))
            new_seq (swap seq- start index_of_smallest_v)]
        (recur new_seq (inc start)))
      seq-)))

(defn qsort-partition [seq pivot_index]
  (let [pivot (seq pivot_index)
    pair (loop [i 0, le [], gt []]
           (if (&lt; i (.length seq))
         (if (&lt;= (seq i) pivot)
           (let [le (cons (seq i) le)]
             (recur (inc i) le gt))
           (let [gt (cons (seq i) gt)]
             (recur (inc i) le gt)))
         [(vec le), (vec gt)]))]
    pair))
</code></pre>

<p>比较一下两个版本排列10000个数的时间：</p>

<pre><code>(time (qsort-seq values))
(time (qsort values))
(shutdown-agents)
</code></pre>

<p>输出</p>

<pre><code>"Elapsed time: 1532.536441 msecs"
"Elapsed time: 1121.529135 msecs"
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://hjiang.net/archives/365/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
