改进这个Clojure代码以获得更多的惯用语

时间:2015-08-17 12:53:15

标签: performance clojure

任何方式我都可以使用以下代码获得更多惯用的Clojure。我知道我遗漏了一些关于解构的事情。至少我可以说我理解当前的代码。我的第一个诱惑是使用doseq,然后填充hash-map,但我确信map是解决方案。

代码读取CSV文件 -

Name,Department,Score
Rohan,IT,8
Bob,Sales,6
Tom,IT,9
Jane,Accounting,3
Mary,Sales,9
Harry,IT,8
Frodo,Marketing,8
Bilbo,Accounting,10

并输出按最高分数排序的行。简单!

(def file "scores.csv")

(defn list-of-vecs []
  (let [file-str (slurp file)]
    (let [lines (clojure.string/split-lines file-str)]
      (next (map #(clojure.string/split % #",") lines)))))

(defn list-of-maps []
    (map (fn [n] {:name (n 0), :department (n 1), :score (Integer/parseInt (n 2))})
        (list-of-vecs)))

(defn sorted-list []
  (reverse (sort-by :score (list-of-maps))))

(defn print-high-scores []
  (prn "Name","Department","Score")
  (map (fn [m] (prn (m :name) (m :department) (m :score))) (sorted-list)))

任何反馈都会受到赞赏,包括缩进。

我也对表演感到非常惊讶(在莱恩内跑)。

8行

的CSV文件
parse-csv.core=> (time print-high-scores)
 "Elapsed time: 0.026059 msecs"

25k行

的CSV文件
parse-csv.core=> (time print-high-scores)
"Elapsed time: 0.025636 msecs"

1 个答案:

答案 0 :(得分:1)

您的(time print-high-scores)实际打印了什么吗?

Or am I using time incorrectly

我认为你正确地使用它但测量错误的东西。

我的方法:

; read file - drop header line
(def input 
  (rest (line-seq (clojure.java.io/reader "inputfilename"))))

; top ten
(def top-ten 
  (take 10 (time (sort-by 
              #(- (Integer/parseInt (nth % 2))) ; negate so highest first
              (map (fn [line] 
                     (clojure.string/split line #",")) input)))))
; 10 lines  "Elapsed time:  0.469539 msecs"
; 25k lines "Elapsed time: 68.157863 msecs"

; print - sideeffect
(time (doseq [e (doall top-ten)] 
  (print e "\n")))

"Elapsed time: 0.02804 msecs"
[Bilbo Accounting 10]
[Tom IT 9]
[Mary Sales 9]
[Rohan IT 8]
[Harry IT 8]
[Frodo Marketing 8]
[Bob Sales 6]
[Jane Accounting 3]
nil