The problem is not the freqs function. The implementation in Python
and in Clojure are different algorithms.

Both produce a graph with the number of blocks per layer per type, for
6 particular types. These six types are the Clay, Coal ore, Diamond
ore, Gold ore, Iron ore, Obsidian, and Redstone ore that are plotted
in the graphs in Pepijn's blogpost.

The Python approach only calculates the frequencies for these 6 types.
The Clojure approach calculates the frequency for ALL the types and
then only displays the plot of the 6 types. This is why the freqs
function take such a long time as it does too much.

The implementation in Clojure below only counts the frequencies for
the 6 types. It also only traverses the blocks array only once,
similarly to the suggestion from Benny Tsai.

Counting the frequencies takes 3 seconds on my machine, using Pepijn's
example level as input. This shows that there is no need to apologize
for using Clojure :)

Counting the frequencies of all 92 types takes 40 seconds on my
machine on the example level. I bet this is faster than the Python
algorithm for all types, because the Clojure approach traverses the
blocks array only once. The Python algorithm will traverse each of the
128 layers 92 times.

;; blocks is one big byte array of all the blocks, created by
concatenating all the files
(defn freqs [^bytes blocks]

  (let [freq-layer (vec (repeatedly 128 #(transient {})))

        types #{(byte 56) (byte 49) (byte 16) (byte 15) (byte 14)
(byte 73)}

        size (alength blocks)]

    (loop [idx (int 0)]

      (when (< idx size)

        (let [block (byte (aget blocks idx))]

            (when (types block)

            ;;the work below is only done when block is one of the six
types
            (let [layer (unchecked-remainder idx 128)

                  fl (nth freq-layer layer)]

              (assoc! fl block (inc (get fl block (int 0))))))


          (recur (unchecked-inc idx)))))

     (doall (map persistent! freq-layer))))

The whole file: https://gist.github.com/666228

-Gijs

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to