On Jul 2, 7:13 pm, Nicolas Oury <nicolas.o...@gmail.com> wrote: > Hello, > I just have a look at your code. I was wondering why reflect.Array/getDouble > was faster than aget?
(aget arrayname) actually makes a call to java.lang.reflect.Array/get which looks at the type of data in the array and then does the right thing. Calling java.lang.reflect.Array/getDouble directly saves the time for type resolving (I guess) and gives me a 30% speedup. > And I realized than you create arrays of objects and not array of doubles. > > Have you tried to replace make-array by double-array? I'm using an equivalent of double-array: user> (make-array Double/TYPE 5) #<double[] [...@7f14671e> user> (double-array 5) #<double[] [...@60d8edf8> user> > You can also try to replace the arithmetic by unchecked arithmetic. (Is it > correct from the point of view of the semantic of the VM you are > implementing?). I didn't get to that yet because my profiling shows that the amount of time spent getting values from an array (even when using getDouble) surpasses by far the time spent in any other operation. Of course, my understanding of the JVM profiler logs may be wrong. > Can you try to check in your profiling whether the function you generate get > compiled or not? Looks like my function did not get compiled, here is the java -Xprof log: http://paste.org/8811 On line 10 you can se the method loneclojurian.ovm2$eval__3920$fn__3922.invoke. But you can see that only 0.5% of time is spent in that function. Scroll down to line 44 and you will see the real time wasters: 54.9% 0 + 2413 java.lang.reflect.Array.getDouble 21.0% 0 + 924 java.lang.reflect.Array.setDouble Looks like the JIT compiler decided it would be a waste of time to compile my function and I agree. :) > What function are you running at the top level? Is that a loop where you run > multiple times the same program? This is the contents of benchmark.clj: (require 'loneclojurian.ovm2) (in-ns 'loneclojurian.ovm2) (def machine (init-ovm "/path/to/bin1.obf")) (defn one-run [] (machine) [(aget output-ports 0) (aget output-ports 1) (aget output-ports 2) (aget output-ports 3) (aget output-ports 4)]) (time (dotimes [_ 200000] (one-run))) So, init-ovm returns a function that executes the program, then I define the one-run function that mimics the "real" usage of the VM: execute the program once and then get the values of the first 5 output ports (this is all related to problem 1). So, I think the problem is that this approach of emulating computer memory is quite resource hungry. Either a way needs to be found to make these gets and sets really cheap or I need to rethink the problem. -- IgorR --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---