从地图clojure的向量求和字符串值

red*_*nds -3 clojure map

我有一个地图矢量,如下所示,尽管每个数据集中可能有100个地图:

data({ a:a b:"2" c:t}{ a:b b:"0" c:t}{ a:c b:"-4" c:t}{ a:d b:"100" c:t}{ a:e b:"50" c:t})
Run Code Online (Sandbox Code Playgroud)

我需要产生以下总和:b

values(map :b data)
sum(reduce + (map read-string values)
Run Code Online (Sandbox Code Playgroud)

这给出了期望的结果,但计算时间长,约为每秒1/10.我正在为数十万个数据集执行此操作,因此需要花费大量处理时间来执行此操作.

任何人都可以建议一种更有效/更快的方法吗?

谢谢

Nie*_*lsK 5

在Clojure 1.2.1中,这是您在100/100秒内完成的总计100.000数据集场景的十分之一.它基本上是你的代码(这不是真正有效的clojure语法,但我们得到了要点),但不知何故运行10.000倍.

;generate 10.000 datasets of 100 maps having 10 fields each

(def scenario-data
    (vec (repeatedly 10000
                     (fn [] (vec (repeatedly 100 (fn [] (zipmap
                                                            [:a :b :c :d :e :f :g :h :i :j]
                                                            (repeatedly (fn [] (str (- (rand-int 2000) 1000))))))))))))


;now map the datasets into the reduced sums of the parsed :b fields of each dataset

(time (doall (map (fn [dataset] (reduce (fn [acc mp] (+ acc (Integer/parseInt (:b mp)))) 0 dataset))
                  scenario-data)))
"Elapsed time: 120.43267 msecs"
=> (2248 -6383 7890 ...)
Run Code Online (Sandbox Code Playgroud)

由于这种情况是相当大的内存密集型(10.000数据集〜= 600MB,总计算使用~4GB),我无法在家用机器上运行100.000数据集方案.但是,如果我不将数据集保存在内存中,我可以运行它,但是可以映射到一个惰性序列,而不需要保持它的头部.

(time (doall (map (fn [dataset] (reduce (fn [acc mp] (+ acc (Integer/parseInt (:b mp)))) 0 dataset))
                  (repeatedly 100000
                              (fn [] (repeatedly 100 (fn [] (zipmap
                                                              [:a :b :c :d :e :f :g :h :i :j]
                                                              (repeatedly (fn [] (str (- (rand-int 2000) 1000))))))))))))
"Elapsed time: 30242.371308 msecs"
=> (-4975 -843 1560 ...)
Run Code Online (Sandbox Code Playgroud)

这是计算100.000数据集版本的30秒,包括生成数据所需的所有时间.使用pmap时间大约为一半(4个核心)的切割.

编辑:在具有足够内存的计算机上创建完全实现的100.000数据集需要135秒.在其上运行求和代码需要大约1500毫秒.使用pmap减少到约750毫秒.一个read-string版本是3.5倍〜慢.

TL/DR:如果有足够的内存,您发布的算法可以在1秒内在100.000数据集场景上运行.

请发布您的完整代码,包括您如何阅读并将数据集保存在内存中,并确保这次语法和观察结果都准确无误.由于没有从源头懒洋洋地读取数据集,这可能更多的是内存问题.