The code is available at this URL: http://code.google.com/p/bwhf/ (look at the hu.becliza.andras.bwhf.control.[BinRepParser, BinReplayUnpacker] files)
It is definitely not as dynamic, which helps quite a lot, but I wanted to have something high level and declarative. Thank you for your help, I'll look into the improvements you suggested. Vincent. On Mar 21, 9:40 am, Christophe Grand <christo...@cgrand.net> wrote: > Hello, > > Is the java code online somewhere to compare? (Since your code is an > interpreter for byte-fields specs there's a lot of stuff going to read a > single byte, I wonder if the java code you're benchmarking against is > that dynamic) > > Right now, null-string and read-field-aux are the most time consuming > functions. > > Creating a cons for each byte read is too much overhead, I rewrote > null-string like this (yes it's lower level): > (defn null-string > "Read a nul-terminated string. Stop at \\0 or at length n > whichever comes first." > [#^ByteBuffer buf n] > (let [arr #^"[B" (make-array Byte/TYPE n) > sb (StringBuilder.)] > (.get buf arr) > (areduce arr i append true > (when append > (let [b (aget arr i)] > (when-not (zero? (int b)) > (.append sb (char b)))))))) > > Concerning read-field-aux I rewrote it like that: > (def read-field-aux > (let [getters {Byte get-byte > Short get-short > Integer get-integer}] > (fn [#^ByteBuffer buf n type] > (let [f (getters type)] > (if (== (int n) 1) > (f buf) > (let [arr (make-array Object n)] > (dotimes [i n] > (aset arr i (f buf))) > (vec arr))))))) > > closing over getters (rather than rebuilding it inside the closure) > yielded nearly as much as going "lower level". > > With these two changes, it's the dispatch fn that now dominates. > > Vincent Foley a écrit : > > > > > Here:http://gist.github.com/82352 > > > I have posted memory and cpu profiling figures. > > > On Mar 20, 6:56 am, Christophe Grand <christo...@cgrand.net> wrote: > > >> Hello Vincent, > > >> Vincent Foley a écrit : > > >>> Hello, > > >>> For the past few days, I've been trying, unsuccessfully, to make an > >>> application I wrote faster. A Java program that performs, more or > >>> less, the same task takes 12 seconds (on my machine) to parse 1000 > >>> files; my Clojure program takes nearly 3 minutes. This more than an > >>> order of magnitude slower! Using the profiling tools available with > >>> the JVM, I quickly determined which function was the costliest. I > >>> copied it into a simple script file to profile it in isolation. I > >>> have made the script and the profile results (long!) available at this > >>> URL:http://gist.github.com/82136 > > >> On my box nearly one half of the total time is sepent in the building of > >> arr (and by looking at your profiling data a good chunk of these traces > >> are related to this map call). > >> Better to get it out of the loop. > > >> (let [arr (into-array Byte/TYPE (map byte [7 ; 1 Byte > >> 3 0 97 0 98 0 99 ; 3 Shorts > >> 0 0 100 100 ; 1 Integer > >> 65 66 67 68 69 70 71 72 73 74 > >> ; 10 String > >> 0 0 0 0 0 0 0 0 0 0 ; 10 ignored > >> ])) > >> buf (ByteBuffer/wrap arr)] > >> (time > >> (dotimes [_ 10000] > >> (.position buf 0) > >> (run buf)))) > > >> Can you give the profile results for this code? > > >> Christophe > > >> -- > >> Professional:http://cgrand.net/(fr) > >> On Clojure:http://clj-me.blogspot.com/(en) > > -- > Professional:http://cgrand.net/(fr) > On Clojure:http://clj-me.blogspot.com/(en) --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---