Re: Performance Penalty Converting from Java Code

2009-06-15 Thread tmountain

Thanks for the replies guys. Both solutions outperform the original.
The one using unchecked operations is about 60x faster, which is the
kind of performance I was hoping for. It's good to see that Clojure
has the capacity to do things very quickly. I just need to learn all
the tricks to make it do so. I'm going to use this code as part of a
small agent demo I'm working on. Basically, it's going to take in work
units (MD5'd strings) and run brute force comparisons on them until a
match is found. I can fire up an agent per core and compare
performance numbers as the workload is parallelized. It's really
simple stuff but good for a concurrency beginner like me to explore
with.

Thanks,
Travis

On Jun 14, 10:00 am, tmountain  wrote:
> I've been playing around with rewriting some Java code in Clojure and
> did some simple benchmarking in the process. In this case, there's a
> huge disparity in the performance numbers between the two languages,
> and I'm wondering what the cause may be. The program rotates a string
> from "", "aaab", ..., "". The Java version takes 0.77 seconds
> to complete while the Clojure version takes 22 seconds. I've tried to
> make the scripts relatively isomorphic and have verified that they
> produce the same results. I'm pasting the source below.
>
> tra...@travis-ubuntu:/tmp% time clj base26.clj
> clj base26.clj  21.99s user 1.23s system 85% cpu 27.318 total
>
> tra...@travis-ubuntu:/tmp% time java Base26
> java Base26  0.77s user 0.04s system 78% cpu 1.029 total
>
> clojure version:
>
> (defn base26 [n]
>   (let [seed-string ""
>         s (new StringBuilder seed-string)]
>     (loop [pos (- (count seed-string) 1)
>            x n]
>       (if (> x 0)
>         (let [digit (+ (int \a) (mod x 26))]
>           (. s setCharAt pos (char digit))
>           (if (and (> pos 0) (> x 0))
>             (recur (- pos 1) (/ x 26))
>     (. s toString)))
>
> (doseq [i (range (Math/pow 26 4))]
>     (base26 i))
>
> java version:
>
> import java.lang.StringBuilder;
>
> public class Base26 {
>     public static void main(String[] args) {
>         for (int i = 0; i < Math.pow(26, 4); i++) {
>             Base26.base26(i);
>         }
>     }
>
>     public static String base26(int num) {
>         if (num < 0) {
>             throw new IllegalArgumentException("Only positive numbers
> are supported");
>         }
>         StringBuilder s = new StringBuilder("");
>         for (int pos = 3; pos >= 0 && num > 0 ; pos--) {
>             char digit = (char) ('a' + num % 26);
>             s.setCharAt(pos, digit);
>             num = num / 26;
>         }
>         return s.toString();
>     }
>
> }
>
> I've tried warn-on-reflection, and it didn't report anything.
>
> Thanks,
> Travis
--~--~-~--~~~---~--~~
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: Performance Penalty Converting from Java Code

2009-06-14 Thread Emeka
kedu Travis,

(defn base26 [ n]
 (let [seed-string ""
   s (new StringBuilder seed-string)]
   (loop [ pos (- (count seed-string) 1)
  x n]
 (if (and (> pos 0)(> x 0))
 (do (. s setCharAt pos (char (+ (int \a) (mod x 26
  (recur (- pos 1) (/ x 26)
   (. s toString)))

(doseq [i (range (Math/pow 26 4))]
   (base26 i))

Try the above.

Emeka

--~--~-~--~~~---~--~~
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: Performance Penalty Converting from Java Code

2009-06-14 Thread Parth



On Jun 14, 7:00 pm, tmountain  wrote:
> I've been playing around with rewriting some Java code in Clojure and
> did some simple benchmarking in the process. In this case, there's a
> huge disparity in the performance numbers between the two languages,
> and I'm wondering what the cause may be. The program rotates a string
> from "", "aaab", ..., "". The Java version takes 0.77 seconds
> to complete while the Clojure version takes 22 seconds. I've tried to
> make the scripts relatively isomorphic and have verified that they
> produce the same results. I'm pasting the source below.
>

Here is a clojure version that runs significantly faster
on my system. The main optimizations I have done are
coercion to primitives and using unchecked ops.
As I understand it, the original clojure version is slow
because its safer (checks for overflows etc.).

(defn xbase26 [n]
  (let [seed-string ""
s (new StringBuilder seed-string)
a_val (int \a)]
(loop [pos 3 x (int n)]
  (when (pos? x)
(let [digit (char (+ a_val (unchecked-remainder x 26)))]
  (.setCharAt s pos digit)
  (when (pos? pos)
(recur (int (dec pos)) (unchecked-divide x 26))
(.toString s)))

These are the numbers I see:

;; java
[clojure]% time java -cp .
Base26
java -cp . Base26  0.40s user 0.02s system 88% cpu 0.476 total

;; original
[clojure]% time java -cp .:classes:/home/parthm/src/clojure/
clojure.jar base26
java -cp .:classes:/home/parthm/src/clojure/clojure.jar base26  33.08s
user 1.18s system 99% cpu 34.456 total
[clojure]%

;; optimized
[clojure]% time java -cp .:classes:/home/parthm/src/clojure/
clojure.jar base26
java -cp .:classes:/home/parthm/src/clojure/clojure.jar base26  1.75s
user 0.11s system 104% cpu 1.784 total


While this works well, I more optimization may
be possible by choosing an algorithm thats more suited
and ideomatic for clojure. I suppose that intent here
is to do a micro-benchmark.

Regards,
Parth


> tra...@travis-ubuntu:/tmp% time clj base26.clj
> clj base26.clj  21.99s user 1.23s system 85% cpu 27.318 total
>
> tra...@travis-ubuntu:/tmp% time java Base26
> java Base26  0.77s user 0.04s system 78% cpu 1.029 total
>
> clojure version:
>
> (defn base26 [n]
>   (let [seed-string ""
>         s (new StringBuilder seed-string)]
>     (loop [pos (- (count seed-string) 1)
>            x n]
>       (if (> x 0)
>         (let [digit (+ (int \a) (mod x 26))]
>           (. s setCharAt pos (char digit))
>           (if (and (> pos 0) (> x 0))
>             (recur (- pos 1) (/ x 26))
>     (. s toString)))
>
> (doseq [i (range (Math/pow 26 4))]
>     (base26 i))
>
> java version:
>
> import java.lang.StringBuilder;
>
> public class Base26 {
>     public static void main(String[] args) {
>         for (int i = 0; i < Math.pow(26, 4); i++) {
>             Base26.base26(i);
>         }
>     }
>
>     public static String base26(int num) {
>         if (num < 0) {
>             throw new IllegalArgumentException("Only positive numbers
> are supported");
>         }
>         StringBuilder s = new StringBuilder("");
>         for (int pos = 3; pos >= 0 && num > 0 ; pos--) {
>             char digit = (char) ('a' + num % 26);
>             s.setCharAt(pos, digit);
>             num = num / 26;
>         }
>         return s.toString();
>     }
>
> }
>
> I've tried warn-on-reflection, and it didn't report anything.
>
> Thanks,
> Travis
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Performance Penalty Converting from Java Code

2009-06-14 Thread tmountain

I've been playing around with rewriting some Java code in Clojure and
did some simple benchmarking in the process. In this case, there's a
huge disparity in the performance numbers between the two languages,
and I'm wondering what the cause may be. The program rotates a string
from "", "aaab", ..., "". The Java version takes 0.77 seconds
to complete while the Clojure version takes 22 seconds. I've tried to
make the scripts relatively isomorphic and have verified that they
produce the same results. I'm pasting the source below.

tra...@travis-ubuntu:/tmp% time clj base26.clj
clj base26.clj  21.99s user 1.23s system 85% cpu 27.318 total

tra...@travis-ubuntu:/tmp% time java Base26
java Base26  0.77s user 0.04s system 78% cpu 1.029 total

clojure version:

(defn base26 [n]
  (let [seed-string ""
s (new StringBuilder seed-string)]
(loop [pos (- (count seed-string) 1)
   x n]
  (if (> x 0)
(let [digit (+ (int \a) (mod x 26))]
  (. s setCharAt pos (char digit))
  (if (and (> pos 0) (> x 0))
(recur (- pos 1) (/ x 26))
(. s toString)))

(doseq [i (range (Math/pow 26 4))]
(base26 i))

java version:

import java.lang.StringBuilder;

public class Base26 {
public static void main(String[] args) {
for (int i = 0; i < Math.pow(26, 4); i++) {
Base26.base26(i);
}
}

public static String base26(int num) {
if (num < 0) {
throw new IllegalArgumentException("Only positive numbers
are supported");
}
StringBuilder s = new StringBuilder("");
for (int pos = 3; pos >= 0 && num > 0 ; pos--) {
char digit = (char) ('a' + num % 26);
s.setCharAt(pos, digit);
num = num / 26;
}
return s.toString();
}
}

I've tried warn-on-reflection, and it didn't report anything.

Thanks,
Travis
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---