Oops, sorry, got my terminology wrong. The sub-arrays represent *layers*, not levels. So the code should actually read as follows:
(def num-layers 128) (defn get-layer [layer-num ^bytes blocks] (let [size (/ (count blocks) num-layers) output (byte-array size)] (doseq [output-idx (range size)] (let [block-idx (+ (* output-idx num-layers) layer-num)] (aset output output-idx (aget blocks block-idx)))) output)) (defn afrequencies [^bytes a] (persistent! (areduce a idx counts (transient {}) (let [x (aget a idx)] (assoc! counts x (inc (get counts x 0))))))) (defn freqs [^bytes blocks] (let [layers (map #(get-layer % blocks) (range num-layers))] (map afrequencies layers))) On Nov 5, 4:57 pm, Benny Tsai <benny.t...@gmail.com> wrote: > Here's what I have so far. The code splits blocks into 128 smaller > sub-arrays, each representing a level, then calls a modified version > of frequencies (using areduce instead of reduce) on each level. On my > machine, with server mode on, it takes about 20 seconds to compute the > frequencies for an array of 99844096 blocks. I haven't tested it on > your level, because I'm too lazy to get JNBT set up, but I'm curious > to see if it returns the correct result for you. > > (def num-levels 128) > > (defn get-level [level-num ^bytes blocks] > (let [size (/ (count blocks) num-levels) > output (byte-array size)] > (doseq [output-idx (range size)] > (let [block-idx (+ (* output-idx num-levels) level-num)] > (aset output output-idx (aget blocks block-idx)))) > output)) > > (defn afrequencies > [^bytes a] > (persistent! > (areduce a > idx > counts > (transient {}) > (let [x (aget a idx)] > (assoc! counts x (inc (get counts x 0))))))) > > (defn freqs [^bytes blocks] > (let [levels (map #(get-level % blocks) (range num-levels))] > (map afrequencies levels))) > > user=> (def blocks (byte-array 99844096)) > #'user/blocks > user=> (time (count (freqs blocks))) > "Elapsed time: 20160.780769 msecs" > 128 > > On Nov 4, 3:28 pm, Pepijn de Vos <pepijnde...@gmail.com> wrote: > > > > > > > > > Hi all, > > > I have written a Python script to analyze Minecraft levels and render a > > graph. Then I did the same with Clojure. It takes Python 10 seconds to > > analyze a map, while it takes Clojure over a minute. > > > After having tried different options without any significant improvement, I > > am lost as to why there is such a huge difference. I wouldn't mind an extra > > pair of eyes/brains to look at this. > > > I blogged about it in more detail > > here:http://pepijndevos.nl/clojure-versus-python > > Clojure version:https://github.com/pepijndevos/Clomian/ > > Python version:https://github.com/l0b0/mian > > > Clojure spends most of its time in the freqs function, here are a couple of > > variations:https://gist.github.com/663096 > > > If you want to run the code yourself, you'll need a Minecraft level and > > JNBT, which is not on Maven. > > JNBT:http://jnbt.sourceforge.net/ > > The level used in the blogpost:http://dl.dropbox.com/u/10094764/World2.zip > > > Groeten, > > Pepijn de Vos > > -- > > Sent from my iPod Shufflehttp://pepijndevos.nl -- 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