I took a stab at it. I used:
(set! *warn-on-reflection* true)
but it didn't tell me anything.

I found a Java class that did the same thing and created a Clojure
implementation from that. I thought that perhaps if I could force the
data types to be BigInteger Clojure would save time by not having to
use reflection.

However, this fails and I'm not sure why. The code:

(defn lpf3 [#^bigint arg]
  (print (str "The prime factorization of "  arg  " is :"))
  (println (loop [i (bigint 2) n (bigint arg) ]
    ;(println (str "i:" i "n:" n))
  (if (<= i (/ n i))
      (recur (inc i) (loop [n2 (bigint n)]
               ;(println (str "n2:" n2))
               (if (zero? (rem n2 i))
                 (recur (/ n2 i) )
                 n2 )))
    n)))
  )

The error:
The prime factorization of 234 is :#<CompilerException
java.lang.ClassCastException: java.lang.Integer cannot be cast to
java.math.BigInteger (REPL:17)>
NOTE: Line 17 in this case looks like "n2 )))"

I tried to create a version using long to see if that would help. It
did as I received better compiler error messages. The end result:
(too many casts perhaps...)
(defn lpf6 [arg]
    (print (str "The prime factorization of "  arg  " is :"))
    (println (loop [i (long 2) n (long arg) ]
        (if (<= i  (/ n i))
          (recur (long (inc i)) (long (loop [n2 (long n)]
            (if (zero? (rem n2 i))
              (recur (long (/ n2 i)) )
              n2 ))))
        (long n))))
)

Clojure=> (time (lpf6 364362978))
The prime factorization of 364362978 is :8675309
"Elapsed time: 133.974784 msecs"

Your code on the same machine gives:
Clojure=> (time (lpf 364362978 2))
"Elapsed time: 1014.572527 msecs"
8675309

I suspect casting to long would speed things up a bit in your case.
However, long doesn't have enough precision to handle the number you
mentioned in your article:
1234567890123456789012345678901234567890

The correct solution would be to coerce the types to bigint. I've done
this and the results are interesting. Strangely bigint is over 10x
faster than long:

Clojure=> (time (lpf6b 364362978))
The prime factorization of 364362978 is :8675309
"Elapsed time: 8.874452 msecs"

The code:

(defn lpf6b [arg]
    (print (str "The prime factorization of "  arg  " is :"))
    (println (loop [i (bigint 2) n (bigint arg) ]
        (if (<= i  (/ n i))
        (recur (bigint (inc i)) (bigint (loop [n2 (bigint n)]
        (if (zero? (rem n2 i))
        (recur (bigint (/ n2 i)) )
        n2 ))))
        (bigint n))))
)

I can only guess that bigint is faster here because I was not casting
long correctly in enough (or in the correct) places and was actually
causing the compiler more work. If this is obvious to anyone please
post. I'm intrigued.

My next stab would have been in GLSL with Clojure Penumbra. Purely for
fun :-) But I'm out of time.

Cheers.


--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to