Re: Why is this code so slow?
On Sat, Feb 02, 2013 at 06:28:09PM -0800, Alexandros Bantis wrote: Hello all. I'm working through the Project Euler problems in Java, Scala, Clojure (trying to learn all three?!?). I notice that for one particular problem, I use--more or less--a similar algorithm for all three, but the clojure code runs about 20-30 times slower than the java/scala versions. Does anyone have any idea why this might be? It strikes me that it might have something to do with every? but I don't know because I'm a newbie with Clojure. Daniel Solano Gómez gave a very interesting talk last summer about numerical performance in Clojure: http://www.infoq.com/presentations/Crunching-Numbers-Clojure While there are many technical tips about boosting math performance, Daniel's overarching point is that the best speed boost is the _right algorithm_. For instance, this solution to the problem runs in ~2ms: ``` (def primes This should be a lazy-seq of primes generated by a bit-sieve, but for this example the largest prime we need is 3! [2 3]) (defn prime-factors [n] (loop [n n fs []] (if-let [p (first (for [p primes :while (= p (int (Math/sqrt n))) :when (zero? (rem n p))] p))] (recur (/ n p) (conj fs p)) (conj fs n (defn lcm The lowest common multiple of a set of numbers is the product of the distinct prime factors in the set each raised to the power of the greatest occurence in a single number. [ xs] (let [fqs (map #(frequencies (prime-factors %)) xs)] (apply * (map (fn [p] (Math/pow p (apply max (map #(get % p 0) fqs (set (mapcat keys fqs)) (time (long (apply lcm (range 2 21 Elapsed time: 2.010032 msecs 232792560 ``` I know you are explicitly asking for language implementation differences, but I believe you would be better served in this instance by studying more elegant algorithms. The fastest code in any language is the code that does not execute; designing with this in mind is especially important in Clojure, where the functional abstractions are beautiful, but somewhat costly. guns -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Question: Looking at Noir code - hey, are those singletons?
On Thu, Sep 13, 2012 at 12:56:47PM -0400, Chas Emerick wrote: One of the great advantages of Ring (and other purely functional bits that stack on top, like Compojure, Bishop, etc) is that its handlers are readily composable. Among other things, this means that way you compose handlers from two different namespaces in the same app is fundamentally no different than the way you compose handlers from N different applications (which can come from different projects, maintained by different teams, etc). Combined with something like Compojure's nested routes[1], this is a simple and powerful way to build modular web apps and services by default. Coming from the Ruby world, I was initially drawn to Noir by it's Sinatra-esque API, but like the OP, I was a little dismayed by the magic of defpage and the like. I am, after all, coming to Clojure so that I can be explicit about my data and my state. Thankfully, Noir is a fairly thin layer over Ring, Compojure, and Hiccup, so creating routes and composing them in just the way Chas mentions was easy and quite satisfying. Of course, Noir is not thereby superfluous; the end result for my app is still a namespaced var holding an atom of the app's handlers. It is explicit and more flexible, but it took more time and typing than a beginner may want to invest. guns -- 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
Re: ForkJoinTask not found under Java 7?
Jim - FooBar(); jimpil1...@gmail.com writes: I thought I did not need the jsr166y.jar under java 7...what is happening? Has clojure 1.5 apha3 been aot-compiled against java 6? It certainly looks that way. The compile-if macro [1] in clojure.core.reducers conditionally defines several vars at runtime, which would be defeated by precompilation. For instance, getting the source for clojure.core.reducers/pool from Java 7 returns: (def pool (delay (jsr166y.ForkJoinPool.))) I don't have a solution myself, but I've been playing with the reducers library by simply stripping the class files from the zip file: $ zip clojure-1.5.0-alpha3.jar -d clojure/core/reducers*.class guns [1]: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L37 -- 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
Re: == is not always transitive
Leif leif.poor...@gmail.com writes: I'd also like to make sure people are aware of this oddity. I discovered this after reading an article about the bad design of PHP. I read that in PHP, == is not transitive. I thought Ha ha ha, that ridiculous PHP! Then I checked c.c/== ; Imagine my reaction when I learned that Clojure had something in common with PHP. o_O, :'[ Other emoticons also washed over me. Clojure's == is numerical equivalence, not equality. - clojure.core/== ([x] [x y] [x y more]) Returns non-nil if nums all have the equivalent value (type-independent), otherwise false The problem with PHP (and JavaScript's) == operator is that the type coercion is not limited to numerical types: PHP 1 == 1= true 1 + 1 = 2 JavaScript 1 == 1= true 1 + 1 = 11 Clojure (== 1 1) = java.lang.ClassCastException (+ 1 1) = java.lang.ClassCastException Clojure's equality function [1], however, does what you expect when comparing floats and integers: (= 1.0 1) = false But it also does what you want when comparing _categories_ of numbers [2] [3]: (let [a (int 1) b (bigint 1)] {:equal_values? (= a b) :equal_types? (= (type a) (type b))}) = {:equal_values? true, :equal_types? false} I think Clojure does a fantastic job of being both convenient and strongly typed. -- guns [1]: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L23 [2]: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L213 [3]: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L978 If you were really concerned about whether a number is a BigInteger vs Integer, or Float vs Double, you would have to handle that on your own. -- 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