Re: Why is this code so slow?

2013-02-05 Thread Sung Pae
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?

2012-09-16 Thread Sung Pae
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?

2012-08-21 Thread Sung Pae
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

2012-04-13 Thread Sung Pae
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