[英]Why is my Clojure code running so slowly?
Below is my answer for 4clojure Problem 108 以下是我对4clojure 问题108的回答
I'm able to pass the first three tests but the last test times out. 我能够通过前三个测试,但最后一个测试超时。 The code runs really, really slowly on this last test.
在最后的测试中,代码运行非常缓慢。 What exactly is causing this?
到底是什么原因造成的?
((fn [& coll] (loop [coll coll m {}]
(do
(let [ct (count coll)
ns (mapv first coll)
m' (reduce #(update-in %1 [%2] (fnil inc 0)) m ns)]
(println m')
(if (some #(<= ct %) (mapv m' ns))
(apply min (map first (filter #(>= (val %) ct) m')))
(recur (mapv rest coll) m'))))))
(map #(* % % %) (range)) ;; perfect cubes
(filter #(zero? (bit-and % (dec %))) (range)) ;; powers of 2
(iterate inc 20))
You are gathering the next value from every input on every iteration (recur (mapv rest coll) m')
您正在从每次迭代的每个输入中收集下一个值
(recur (mapv rest coll) m')
One of your inputs generates values extremely slowly, and accellarates to very high values very quickly: (filter #(zero? (bit-and % (dec %))) (range))
. 您的输入之一将非常缓慢地生成值,并且非常快地将其加速到非常高的值:(
(filter #(zero? (bit-and % (dec %))) (range))
。
Your code is spending most of its time discovering powers of two by incrementing by one and testing the bits. 您的代码大部分时间都是通过递增1并测试位来发现2的幂。
You don't need a map of all inputs with counts of occurrences. 您不需要包含发生次数的所有输入的映射。 You don't need to find the next value for items that are not the lowest found so far.
您无需为到目前为止尚未找到的最低项目找到下一个值。 I won't post a solution since it is an exercise, but eliminating the lowest non matched value on each iteration should be a start.
我不会发布解决方案,因为这是一个练习,但是消除每次迭代中的最低不匹配值应该是一个开始。
This is a really inefficient way of counting powers of 2: 这是计算2的幂的一种非常低效的方式:
(filter #(zero? (bit-and % (dec %))) (range))
This is essentially counting from 0 to infinity, testing each number along the way to see if it's a power of two. 这实际上是从0到无穷大计数,并一路测试每个数字是否为2的幂。 The further you get into the sequence, the more expensive each call to
rest
is. 您进入序列的时间越长,每个
rest
电话就越昂贵。
Given that it's the test input, and you can't change it, I think you need to re-think your approach. 鉴于它是测试输入,并且您无法更改,我认为您需要重新考虑您的方法。 Rather than calling
(mapv rest coll)
, you probably only want to call rest
on the sequence with the smallest first value. 而不是调用
(mapv rest coll)
,您可能只想在第一个值最小的序列上调用rest
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.