Re: Let's see how fast we can make this
I don't know why I thought Java used UTF-8, thank you for the correction. So yeah, would be interesting to see the tests on C done with wide char in UTF-16. On Dec 26, 1:54 am, Glen Stampoultzis wrote: > On 26 December 2010 03:00, Ivan wrote: > > > Would be interesting to see tests done on UTF-8 strings as this is the > > only type that Java supports. > > Do you mean UTF-16? -- 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: Let's see how fast we can make this
On 26 December 2010 03:00, Ivan wrote: > Would be interesting to see tests done on UTF-8 strings as this is the > only type that Java supports. > Do you mean UTF-16? -- 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: Let's see how fast we can make this
Would be interesting to see tests done on UTF-8 strings as this is the only type that Java supports. On a side note, Merry Christmas everyone! Ivan. On Dec 25, 4:52 am, Michael Gardner wrote: > On Dec 24, 2010, at 8:19 PM, David Nolen wrote: > > > ((long double) end-start) / 1000.0 > > I don't think this math is correct. The units for the values returned by > mach_absolute_time() are > CPU-dependent:http://developer.apple.com/library/mac/#qa/qa2004/qa1398.html > > Using gettimeofday() on my 2.0 GHz Core 2 Duo Macbook, I get minima of ~3400 > microseconds for unoptimized C, ~800 microseconds for -O2. > > #include > #include > > unsigned count_chars(char const * s) { > unsigned count = 0; > while (*s++) > if (*s != ' ') > ++count; > return count; > > } > > int main(int argc, char** argv) { > char const * s = "This is a really long stringThis is a really long > stringThis is a really long stringThis is a really long stringThis is a > really long stringThis is a really long stringThis is a really long > stringThis is a really long stringThis is a really long stringThis is a > really long stringThis is a really long stringThis is a really long > stringThis is a really long stringThis is a really long stringThis is a > really long stringThis is a really long stringThis is a really long > stringThis is a really long stringThis is a really long stringThis is a > really long string"; > unsigned i, j; > struct timeval start, end; > > for (j = 0; j < 10; ++j) { > gettimeofday(&start, 0); > for (i = 0; i < 1000; ++i) > count_chars(s); > gettimeofday(&end, 0); > printf("%u us\n", (unsigned)(100 * (end.tv_sec - start.tv_sec) + > (end.tv_usec - start.tv_usec))); > } > > return(0); > > > > > > > > } -- 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: Let's see how fast we can make this
On Dec 24, 2010, at 8:19 PM, David Nolen wrote: > ((long double) end-start) / 1000.0 I don't think this math is correct. The units for the values returned by mach_absolute_time() are CPU-dependent: http://developer.apple.com/library/mac/#qa/qa2004/qa1398.html Using gettimeofday() on my 2.0 GHz Core 2 Duo Macbook, I get minima of ~3400 microseconds for unoptimized C, ~800 microseconds for -O2. #include #include unsigned count_chars(char const * s) { unsigned count = 0; while (*s++) if (*s != ' ') ++count; return count; } int main(int argc, char** argv) { char const * s = "This is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long string"; unsigned i, j; struct timeval start, end; for (j = 0; j < 10; ++j) { gettimeofday(&start, 0); for (i = 0; i < 1000; ++i) count_chars(s); gettimeofday(&end, 0); printf("%u us\n", (unsigned)(100 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec))); } return(0); } -- 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: Let's see how fast we can make this
On Sat, Dec 25, 2010 at 11:28 AM, David Nolen wrote: > On Fri, Dec 24, 2010 at 8:19 PM, David Nolen wrote: > >> On OS X at least the following program shows identical performance to the >> JVM using 64 bit integers, ~2000 nanoseconds on my machine. So Clojure is >> not too far behind. >> > > w/o any GCC optimizations of course. With O2, the C is twice as fast on > this particularly micro microbenchmark. > On my "newish" Macbook I compiled and tested your code. I changed the thousand loop to a million loop and your code went from ~1000ns to ~600ns w/ O2 optimization. > In anycase, Clojure is no slouch :) > I agree 100%, but I've been surprised to find such significant performance improvements in my own code by incorporating JNI for certain hot spots. -- 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: Let's see how fast we can make this
On Fri, Dec 24, 2010 at 8:19 PM, David Nolen wrote: > On OS X at least the following program shows identical performance to the > JVM using 64 bit integers, ~2000 nanoseconds on my machine. So Clojure is > not too far behind. > w/o any GCC optimizations of course. With O2, the C is twice as fast on this particularly micro microbenchmark. In anycase, Clojure is no slouch :) David -- 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: Let's see how fast we can make this
On Fri, Dec 24, 2010 at 7:32 PM, Alan Busby wrote: > On Fri, Dec 24, 2010 at 7:10 PM, Devrim Baris Acar > wrote: > >> I guess it would be a better guess if you could includethe cpu type/speed >> for a rough reference... > > > It was on an Intel Xeon E5410 (2.33GHz), though like others have already > said there are a number of factors that affect performance. I was simply > curious of the relative speeds of the various code snippets on a production > server. > > Also, I tried the C version using unsigned long long ints (64bit) and it > was roughly the same speed. > On OS X at least the following program shows identical performance to the JVM using 64 bit integers, ~2000 nanoseconds on my machine. So Clojure is not too far behind. #import #include "stdio.h" long long count_chars(const char* s) { long long count = 0; long long i; for(i=0; s[i]; s++) { if(s[i] != 32) { count++; } } return count; } int main(int argc, char** argv) { const char *s = "This is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long stringThis is a really long string"; long long i; long long j; for(j = 0; j < 10; j++) { uint64_t start = mach_absolute_time(); for(i = 0; i < 1000; i++) { count_chars(s); } uint64_t end = mach_absolute_time(); printf("%Lf nanoseconds\n", ((long double) end-start) / 1000.0); } exit(0); } David -- 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: Let's see how fast we can make this
On Fri, Dec 24, 2010 at 7:10 PM, Devrim Baris Acar wrote: > I guess it would be a better guess if you could includethe cpu type/speed > for a rough reference... It was on an Intel Xeon E5410 (2.33GHz), though like others have already said there are a number of factors that affect performance. I was simply curious of the relative speeds of the various code snippets on a production server. Also, I tried the C version using unsigned long long ints (64bit) and it was roughly the same speed. -- 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: Let's see how fast we can make this
I guess it would be a better guess if you could includethe cpu type/speed for a rough reference... Devrim Baris Acar On Fri, Dec 24, 2010 at 09:55, Alan Busby wrote: > Hi All, > > > On Fri, Dec 24, 2010 at 4:32 PM, Meikel Brandmeyer wrote: > > Most interesting is also the relation between the different versions on >> the given machine. Just the numbers of one algorithm aren't really >> comparable, I guess. (different machine, different load, different phase of >> moon, who knows...) >> > > Did the below just for my own amusement on a 64bit linux box, and thought > it might be interesting to others. The fastest implementation was using > areduce with 1.3.0-alpha and unchecked ops for 2800ns. Unoptimized C was > doing 700ns though, and with -O2 it was 400ns. Reminds me why JNI can be so > valuable sometimes. > > > /* -O0 low of 700ns > -02 low of 400ns */ > int char_count(char* ptr) > { > int count = 0; > int i; > > for(i=0; ptr[i]; ptr++) > if(ptr[i]!=32) > count++; > > return count; > } > > > ;; 1.2.0 low of 65000ns > > > > ;; 1.3.0-alpha3 low of 46000ns > > > > ;; > > > > (defn count-num-chars-v1 [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > > ;; 1.2.0 low of 6200ns > > > > ;; 1.3.0-alpha3 low of 4800ns > > > > ;; > > > > (defn count-num-chars-v2 [^String s] > (let [len (.length s) > space (int 32)] > (loop [i (int 0), c (int 0)] > (if (< i len) > (recur > (inc i) > (if (== (.codePointAt s i) space) >c >(unchecked-inc c))) >c > > > ;; 1.2.0 low of 12500ns > > > > ;; 1.3.0-alpha3 low of 4450ns > > > > ;; 1.3.0-alpha3 with *unchecked-math* enabled low of 2800ns > > > > ;; > > > > (defn count-num-chars-v3 [^String s] > (let [as (.toCharArray s)] >(areduce as idx acc 0 (if (= (int (aget as idx)) (int \space)) acc > (inc acc) > > > ;; 1.2.0 untested > > > > ;; 1.3.0-alpha3 low of 4500ns > > > > ;; > > > > (defn count-num-chars-v4 ^long [^String s] > (let [l (.length s) > c \space] > (loop [i 0 acc 0] > (if (< i l) > (recur (inc i) >(if (identical? (.charAt s i) c) acc >(inc acc))) > acc > > > Hope this helps, > Alan > > -- > 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 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: Let's see how fast we can make this
On Fri, Dec 24, 2010 at 2:55 AM, Alan Busby wrote: > Hi All, > > > On Fri, Dec 24, 2010 at 4:32 PM, Meikel Brandmeyer wrote: > > Most interesting is also the relation between the different versions on >> the given machine. Just the numbers of one algorithm aren't really >> comparable, I guess. (different machine, different load, different phase of >> moon, who knows...) >> > > Did the below just for my own amusement on a 64bit linux box, and thought > it might be interesting to others. The fastest implementation was using > areduce with 1.3.0-alpha and unchecked ops for 2800ns. Unoptimized C was > doing 700ns though, and with -O2 it was 400ns. Reminds me why JNI can be so > valuable sometimes. > In order to be fair you probably need to remember to switch your C arithmetic operations to 64bit longs. David -- 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: Let's see how fast we can make this
Hi All, On Fri, Dec 24, 2010 at 4:32 PM, Meikel Brandmeyer wrote: > Most interesting is also the relation between the different versions on the > given machine. Just the numbers of one algorithm aren't really comparable, I > guess. (different machine, different load, different phase of moon, who > knows...) > Did the below just for my own amusement on a 64bit linux box, and thought it might be interesting to others. The fastest implementation was using areduce with 1.3.0-alpha and unchecked ops for 2800ns. Unoptimized C was doing 700ns though, and with -O2 it was 400ns. Reminds me why JNI can be so valuable sometimes. /* -O0 low of 700ns -02 low of 400ns */ int char_count(char* ptr) { int count = 0; int i; for(i=0; ptr[i]; ptr++) if(ptr[i]!=32) count++; return count; } ;; 1.2.0 low of 65000ns ;; 1.3.0-alpha3 low of 46000ns ;; (defn count-num-chars-v1 [^String s] (loop [s s acc 0] (if (seq s) (recur (rest s) (if (= (first s) \space) acc (inc acc))) acc))) ;; 1.2.0 low of 6200ns ;; 1.3.0-alpha3 low of 4800ns ;; (defn count-num-chars-v2 [^String s] (let [len (.length s) space (int 32)] (loop [i (int 0), c (int 0)] (if (< i len) (recur (inc i) (if (== (.codePointAt s i) space) c (unchecked-inc c))) c ;; 1.2.0 low of 12500ns ;; 1.3.0-alpha3 low of 4450ns ;; 1.3.0-alpha3 with *unchecked-math* enabled low of 2800ns ;; (defn count-num-chars-v3 [^String s] (let [as (.toCharArray s)] (areduce as idx acc 0 (if (= (int (aget as idx)) (int \space)) acc (inc acc) ;; 1.2.0 untested ;; 1.3.0-alpha3 low of 4500ns ;; (defn count-num-chars-v4 ^long [^String s] (let [l (.length s) c \space] (loop [i 0 acc 0] (if (< i l) (recur (inc i) (if (identical? (.charAt s i) c) acc (inc acc))) acc Hope this helps, Alan -- 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: Let's see how fast we can make this
Hi, Am 24.12.2010 um 02:08 schrieb Ken Wesson: > It's also possible that -server vs. -client is an issue here, also > running it a few times in a row so JIT will have kicked in. I used > -server and ran each test a few times until the numbers settled down > before posting my timings here; I'm not sure if everyone else did > likewise. One might want to use criterium[1] for such things. It tries to avoid such pitfalls. And even if not perfect it would give the same basis for everyone doing the benchmark. Most interesting is also the relation between the different versions on the given machine. Just the numbers of one algorithm aren't really comparable, I guess. (different machine, different load, different phase of moon, who knows...) Sincerely Meikel [1]: http://hugoduncan.org/post/2010/benchmarking_clojure_code_with_criterium.xhtml -- 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: Let's see how fast we can make this
On Thu, Dec 23, 2010 at 5:10 PM, Sean Corfield wrote: > On Thu, Dec 23, 2010 at 12:31 PM, Mark Engelberg > wrote: >> Any ideas why people are getting such radically different results on >> their machines? It's hard for library writers to write any kind of >> optimized code if "optimized" on one machine means "slower" on >> another. > > FWIW, I've experienced radically different performance of identical > code on Windows vs Mac vs Linux due to JVM differences. It's also possible that -server vs. -client is an issue here, also running it a few times in a row so JIT will have kicked in. I used -server and ran each test a few times until the numbers settled down before posting my timings here; I'm not sure if everyone else did likewise. -- 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: Let's see how fast we can make this
On Thu, Dec 23, 2010 at 12:31 PM, Mark Engelberg wrote: > Any ideas why people are getting such radically different results on > their machines? It's hard for library writers to write any kind of > optimized code if "optimized" on one machine means "slower" on > another. FWIW, I've experienced radically different performance of identical code on Windows vs Mac vs Linux due to JVM differences. Mostly that's from the CFML world where folks try to do A/B performance comparisons on "optimized" code vs original code - and this is especially so when trying to compare performance of the different engines: Adobe (commercial vs Railo / Open BlueDragon (both free open source)... -- Sean A Corfield -- (904) 302-SEAN Railo Technologies, Inc. -- http://getrailo.com/ An Architect's View -- http://corfield.org/ "If you're not annoying somebody, you're not really alive." -- Margaret Atwood -- 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: Let's see how fast we can make this
Any ideas why people are getting such radically different results on their machines? It's hard for library writers to write any kind of optimized code if "optimized" on one machine means "slower" on another. -- 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: Let's see how fast we can make this
On Thu, Dec 23, 2010 at 3:03 PM, Remco van 't Veer wrote: > On my system it is about 10x faster than the code in the original > thread. Together with the amount of time saved writing it, it's full > seconds, maybe even minutes faster! I guess your nanoseconds and are > not my nanoseconds.. ;) On my machine your method is about 56X slower. Which isn't to say I wouldn't reach for your method first 99% of time :) David -- 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: Let's see how fast we can make this
On 2010/12/23 18:30, Ken Wesson wrote: > On Thu, Dec 23, 2010 at 3:24 AM, Remco van 't Veer wrote: >> Simpler and faster: >> >> (count (clojure.string/replace s " " "")) > > Simpler, yes, but not at all faster: > > Time (in nanoseconds): 120485.9396 > > This is about comparable to the slow, unoptimized loop posted at the > start of this thread. Frankly, I'm surprised it's not even worse since > it creates a whole extra string object on top of that. On my system it is about 10x faster than the code in the original thread. Together with the amount of time saved writing it, it's full seconds, maybe even minutes faster! I guess your nanoseconds and are not my nanoseconds.. ;) -- 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: Let's see how fast we can make this
(set! *unchecked-math* true) (defn count-num-chars ^long [^String s] (let [l (.length s) c \space] (loop [i 0 acc 0] (if (< i l) (recur (inc i) (if (identical? (.charAt s i) c) acc (inc acc))) acc Clojure 1.3.0-master-SNAPSHOT gives < 2700ns-2900ns David -- 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: Let's see how fast we can make this
On Thu, Dec 23, 2010 at 3:24 AM, Remco van 't Veer wrote: > Simpler and faster: > > (count (clojure.string/replace s " " "")) Simpler, yes, but not at all faster: Time (in nanoseconds): 120485.9396 This is about comparable to the slow, unoptimized loop posted at the start of this thread. Frankly, I'm surprised it's not even worse since it creates a whole extra string object on top of that. -- 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: Let's see how fast we can make this
Simpler and faster: (count (clojure.string/replace s " " "")) On 2010/12/22 18:52, Rayne wrote: > I have a piece of code, and I'd like to see how fast it can be. > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > This is the fastest I've been able to get it. The function is very > simple. It takes a string and counts the number of non-space > characters inside of that string. > > I've been testing this code against a 460 non-space character string. > Here is the entire source, benchmarking and all: > > (def s (apply str (repeat 20 "This is a really long string"))) > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > (println "Chars outputted:" (count-num-chars s)) > > (let [before (System/nanoTime)] > (dotimes [_ 1000] > (count-num-chars s)) > (let [after (System/nanoTime)] > (println "Time (in nanoseconds):" (/ (- after before) 1000.0 > > Running it gives me around 137343.295 nanoseconds. I've seen some Java > algorithms that could run at just under 3000 nanoseconds. > > Hide your children and hide your women; I want to see the direst, > nastiest, rawest, fastest possible implementation of this function. -- 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: Let's see how fast we can make this
On Wed, Dec 22, 2010 at 10:19 PM, Rayne wrote: > private static int countNumChars(String s) { > int num = s.length(); > for (int i = 0; i < s.length(); i++) { > if (s.charAt(i) == ' ') { > num--; > } > } > return num; > } > > Is one of the fastest I've seen. It runs around 4366.293 Does it speed up any further if you manually hoist the s.length() out of the loop? It's encouraging that the fastest Clojure implementation we've found takes only ~25% longer on your machine. -- 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: Let's see how fast we can make this
private static int countNumChars(String s) { int num = s.length(); for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == ' ') { num--; } } return num; } Is one of the fastest I've seen. It runs around 4366.293 On Dec 22, 1:43 pm, David Nolen wrote: > On Wed, Dec 22, 2010 at 12:52 PM, Rayne wrote: > > Running it gives me around 137343.295 nanoseconds. I've seen some Java > > algorithms that could run at just under 3000 nanoseconds. > > What do the Java implementations look like? > > (defn count-num-chars [^String s] > (let [l (.length s) > c (int \space)] > (loop [i 0 acc 0] > (if (< i l) > (recur (unchecked-inc-long i) > (if (= (int (.charAt s i)) c) acc > (unchecked-inc-long acc))) > acc > > On 1.3.0 alpha3 on a 2.66ghz Core i7, 64bit OS X JDK 1.6 I see anywhere > from- > > 6900ns-11000ns > > Using identical?, codePointAt all make things slower for me. > > David -- 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: Let's see how fast we can make this
Wednesday, December 22, 2010, 6:52:01 PM, you wrote: > On my machine, your reduce example (I actually wrote that myself as my > first try) runs marginally slower than my loop example. I don't know > why you're getting such weird numbers. Your areduce example is worst > of all at 74072 on my machine. I got those results using: "Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)" With the HEAD version of Clojure from github. Running with no command-line options other than -server. The 32-bit version seems vaguely similar. -- Dave -- 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: Let's see how fast we can make this
On Wed, Dec 22, 2010 at 12:52 PM, Rayne wrote: > Running it gives me around 137343.295 nanoseconds. I've seen some Java > algorithms that could run at just under 3000 nanoseconds. > What do the Java implementations look like? (defn count-num-chars [^String s] (let [l (.length s) c (int \space)] (loop [i 0 acc 0] (if (< i l) (recur (unchecked-inc-long i) (if (= (int (.charAt s i)) c) acc (unchecked-inc-long acc))) acc On 1.3.0 alpha3 on a 2.66ghz Core i7, 64bit OS X JDK 1.6 I see anywhere from- 6900ns-11000ns Using identical?, codePointAt all make things slower for me. David -- 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: Let's see how fast we can make this
On my machine, your reduce example (I actually wrote that myself as my first try) runs marginally slower than my loop example. I don't know why you're getting such weird numbers. Your areduce example is worst of all at 74072 on my machine. On Dec 22, 12:39 pm, David Powell wrote: > Hi, > > > I have a piece of code, and I'd like to see how fast it can be. > > (defn count-num-chars [^String s] > > (loop [s s acc 0] > > (if (seq s) > > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > > acc))) > > I get an average of 46928 for this. > > But for the straightforward option of reduce: > > (defn count-num-chars3 [^String s] > (reduce (fn [acc c] (if (= c \space) acc (inc acc))) 0 s)) > > I get an average of 27424. Cool! So writing it the nicest way, is > also faster. > > I tend to avoid spamming .charAt even in Java for things like this, > and often find converting to an array first to be faster, like this: > > (defn count-num-chars4 [^String s] > (let [as (.toCharArray s)] > (areduce as idx acc 0 (if (= (int (aget as idx)) (int \space)) acc (inc > acc) > > I get an average of 3631. > > (needed to cast the char to int there, else clojure seems to hit > reflection problems) > > -- > Dave -- 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: Let's see how fast we can make this
Hi, > I have a piece of code, and I'd like to see how fast it can be. > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) I get an average of 46928 for this. But for the straightforward option of reduce: (defn count-num-chars3 [^String s] (reduce (fn [acc c] (if (= c \space) acc (inc acc))) 0 s)) I get an average of 27424. Cool! So writing it the nicest way, is also faster. I tend to avoid spamming .charAt even in Java for things like this, and often find converting to an array first to be faster, like this: (defn count-num-chars4 [^String s] (let [as (.toCharArray s)] (areduce as idx acc 0 (if (= (int (aget as idx)) (int \space)) acc (inc acc) I get an average of 3631. (needed to cast the char to int there, else clojure seems to hit reflection problems) -- Dave -- 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: Let's see how fast we can make this
On Wed, Dec 22, 2010 at 1:19 PM, Rayne wrote: > chouser wrote a solution earlier. I and a buddy modified it (a very > little) bit and managed to get it pretty blazing: > > ra...@ubuntu:~$ cake run ~/challenge.clj > Chars outputted: 460 > Time (in nanoseconds): 5768.677 > > Here is the function: > > (defn count-num-chars [^String s] > (let [len (.length s) > space (int 32)] > (loop [i (int 0), c (int 0)] > (if (< i len) > (recur > (inc i) > (if (== (.codePointAt s i) space) > c > (unchecked-inc c))) > c I get about 6000ns with this also. It looks like one bit of Clojure in need of improvement is the handling of the = operator: if at compile time it's known that either side is a primitive or a character constant, it really ought to boil down to a Java == operator, but apparently it doesn't, and JIT and branch prediction don't suffice to render the difference moot. Also, == doesn't seem to work with characters -- ClassCastException java.lang.Character can't be cast to java.lang.Number. This with \space or (char \space) on the right hand side and (.charAt s i) on the left. The odd thing is this suggests == isn't a raw Java == operator call but rather a method call of Number, likely .equals. Which shouldn't be particularly fast. Now, identical? IS supposed to be Java's == operator but for (defn count-num-chars [^String s] (let [l (int (.length s)) c (char \space)] (loop [i (int 0) acc (int 0)] (if (< i l) (recur (unchecked-inc i) (if (identical? (.charAt s i) c) acc (unchecked-inc acc))) acc I get 9000ns, about two-thirds the speed I get using == and .codePointAt. Something interesting is going on among =, ==, and identical? here, but I'm not 100% sure what. Perhaps identical? is not managing to have its function call overhead JITted away, while the Clojure compiler treats the operators specially; in theory it *should* be fastest. -- 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: Let's see how fast we can make this
Also, forgot to add an unchecked-int: (defn count-num-chars [^String s] (let [len (.length s) space (int 32)] (loop [i (int 0), c (int 0)] (if (< i len) (recur (unchecked-inc i) (if (== (int (.charAt s i)) space) c (unchecked-inc c))) c Also, any version of Clojure is fine. On Dec 22, 12:29 pm, Rayne wrote: > I actually pasted the wrong code here: > > (defn count-num-chars [^String s] > (let [len (.length s) > space (int 32)] > (loop [i (int 0), c (int 0)] > (if (< i len) > (recur > (inc i) > (if (== (int (.charAt s i)) space) > c > (unchecked-inc c))) > c > > On Dec 22, 12:19 pm, Rayne wrote: > > > > > chouser wrote a solution earlier. I and a buddy modified it (a very > > little) bit and managed to get it pretty blazing: > > > ra...@ubuntu:~$ cake run ~/challenge.clj > > Chars outputted: 460 > > Time (in nanoseconds): 5768.677 > > > Here is the function: > > > (defn count-num-chars [^String s] > > (let [len (.length s) > > space (int 32)] > > (loop [i (int 0), c (int 0)] > > (if (< i len) > > (recur > > (inc i) > > (if (== (.codePointAt s i) space) > > c > > (unchecked-inc c))) > > c > > > On Dec 22, 11:52 am, Rayne wrote: > > > > I have a piece of code, and I'd like to see how fast it can be. > > > > (defn count-num-chars [^String s] > > > (loop [s s acc 0] > > > (if (seq s) > > > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > > > acc))) > > > > This is the fastest I've been able to get it. The function is very > > > simple. It takes a string and counts the number of non-space > > > characters inside of that string. > > > > I've been testing this code against a 460 non-space character string. > > > Here is the entire source, benchmarking and all: > > > > (def s (apply str (repeat 20 "This is a really long string"))) > > > > (defn count-num-chars [^String s] > > > (loop [s s acc 0] > > > (if (seq s) > > > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > > > acc))) > > > > (println "Chars outputted:" (count-num-chars s)) > > > > (let [before (System/nanoTime)] > > > (dotimes [_ 1000] > > > (count-num-chars s)) > > > (let [after (System/nanoTime)] > > > (println "Time (in nanoseconds):" (/ (- after before) 1000.0 > > > > Running it gives me around 137343.295 nanoseconds. I've seen some Java > > > algorithms that could run at just under 3000 nanoseconds. > > > > Hide your children and hide your women; I want to see the direst, > > > nastiest, rawest, fastest possible implementation of this function. -- 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: Let's see how fast we can make this
I actually pasted the wrong code here: (defn count-num-chars [^String s] (let [len (.length s) space (int 32)] (loop [i (int 0), c (int 0)] (if (< i len) (recur (inc i) (if (== (int (.charAt s i)) space) c (unchecked-inc c))) c On Dec 22, 12:19 pm, Rayne wrote: > chouser wrote a solution earlier. I and a buddy modified it (a very > little) bit and managed to get it pretty blazing: > > ra...@ubuntu:~$ cake run ~/challenge.clj > Chars outputted: 460 > Time (in nanoseconds): 5768.677 > > Here is the function: > > (defn count-num-chars [^String s] > (let [len (.length s) > space (int 32)] > (loop [i (int 0), c (int 0)] > (if (< i len) > (recur > (inc i) > (if (== (.codePointAt s i) space) > c > (unchecked-inc c))) > c > > On Dec 22, 11:52 am, Rayne wrote: > > > > > I have a piece of code, and I'd like to see how fast it can be. > > > (defn count-num-chars [^String s] > > (loop [s s acc 0] > > (if (seq s) > > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > > acc))) > > > This is the fastest I've been able to get it. The function is very > > simple. It takes a string and counts the number of non-space > > characters inside of that string. > > > I've been testing this code against a 460 non-space character string. > > Here is the entire source, benchmarking and all: > > > (def s (apply str (repeat 20 "This is a really long string"))) > > > (defn count-num-chars [^String s] > > (loop [s s acc 0] > > (if (seq s) > > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > > acc))) > > > (println "Chars outputted:" (count-num-chars s)) > > > (let [before (System/nanoTime)] > > (dotimes [_ 1000] > > (count-num-chars s)) > > (let [after (System/nanoTime)] > > (println "Time (in nanoseconds):" (/ (- after before) 1000.0 > > > Running it gives me around 137343.295 nanoseconds. I've seen some Java > > algorithms that could run at just under 3000 nanoseconds. > > > Hide your children and hide your women; I want to see the direst, > > nastiest, rawest, fastest possible implementation of this function. -- 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: Let's see how fast we can make this
On Wed, Dec 22, 2010 at 1:22 PM, Ken Wesson wrote: > > (defn count-num-chars [^String s] > (let [l (int (.length s))] >(loop [i (int 0) acc (int 0)] > (if (< i l) >(recur (unchecked-inc i) (if (= (.charAt s i) \space) acc > (unchecked-inc acc))) >acc > > 15k nsec -- twice as fast as before. Still 5x slower than Java; I'm > not sure why. This is now directly equivalent to the obvious Java > implementation, > If you're on 1.2 performance will suffer from boxing/unboxing numbers as well as vars being dynamically rebindable by default. You should see a reasonable jump in perf for the same code on the latest 1.3 alphas. You can also remove all those 'int' type-hints. David -- 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: Let's see how fast we can make this
On Wed, Dec 22, 2010 at 12:52 PM, Rayne wrote: > I have a piece of code, and I'd like to see how fast it can be. > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > This is the fastest I've been able to get it. The function is very > simple. It takes a string and counts the number of non-space > characters inside of that string. > > I've been testing this code against a 460 non-space character string. > Here is the entire source, benchmarking and all: > > (def s (apply str (repeat 20 "This is a really long string"))) > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > (println "Chars outputted:" (count-num-chars s)) > > (let [before (System/nanoTime)] > (dotimes [_ 1000] > (count-num-chars s)) > (let [after (System/nanoTime)] > (println "Time (in nanoseconds):" (/ (- after before) 1000.0 > > Running it gives me around 137343.295 nanoseconds. I get around half that. Yours calls seq every loop. Writing (defn count-num-chars [^String s] (loop [s (seq s) acc 0] (if s (recur (next s) (if (= (first s) \space) acc (inc acc))) acc))) results in about 10% savings. Using primitive math: (defn count-num-chars [^String s] (loop [s (seq s) acc (int 0)] (if s (recur (next s) (if (= (first s) \space) acc (unchecked-inc acc))) acc))) yields up another 10% or so. That's maybe 40,000ns, still over 10x slower than the Java implementations you mentioned, but it's about the limits of the savings we'll get while still using the seq abstraction, I suspect. To get closer to Java performance means getting closer to Java means of doing it: (defn count-num-chars [^String s] (let [l (int (.length s))] (loop [i (int 0) acc (int 0)] (if (< i l) (recur (unchecked-inc i) (if (= (.charAt s i) \space) acc (unchecked-inc acc))) acc 15k nsec -- twice as fast as before. Still 5x slower than Java; I'm not sure why. This is now directly equivalent to the obvious Java implementation, int l = s.length(); int acc = 0; for (i = 0; i < l; ++i) if (s.charAt(i) == ' ') ++acc; and since the string is type-hinted it shouldn't be using reflection for the length or charAt calls. -- 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: Let's see how fast we can make this
chouser wrote a solution earlier. I and a buddy modified it (a very little) bit and managed to get it pretty blazing: ra...@ubuntu:~$ cake run ~/challenge.clj Chars outputted: 460 Time (in nanoseconds): 5768.677 Here is the function: (defn count-num-chars [^String s] (let [len (.length s) space (int 32)] (loop [i (int 0), c (int 0)] (if (< i len) (recur (inc i) (if (== (.codePointAt s i) space) c (unchecked-inc c))) c On Dec 22, 11:52 am, Rayne wrote: > I have a piece of code, and I'd like to see how fast it can be. > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > This is the fastest I've been able to get it. The function is very > simple. It takes a string and counts the number of non-space > characters inside of that string. > > I've been testing this code against a 460 non-space character string. > Here is the entire source, benchmarking and all: > > (def s (apply str (repeat 20 "This is a really long string"))) > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > (println "Chars outputted:" (count-num-chars s)) > > (let [before (System/nanoTime)] > (dotimes [_ 1000] > (count-num-chars s)) > (let [after (System/nanoTime)] > (println "Time (in nanoseconds):" (/ (- after before) 1000.0 > > Running it gives me around 137343.295 nanoseconds. I've seen some Java > algorithms that could run at just under 3000 nanoseconds. > > Hide your children and hide your women; I want to see the direst, > nastiest, rawest, fastest possible implementation of this function. -- 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: Let's see how fast we can make this
Which version of Clojure are you using? (How to speed that up depends a lot of the version you use) I would like to see a with a longer run. Optimised clojure is *asymptotically* nearly as fast as Java. With under 1000 calls I am not sure the JIT is called. Best, Nicolas. On Wed, Dec 22, 2010 at 5:52 PM, Rayne wrote: > I have a piece of code, and I'd like to see how fast it can be. > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > This is the fastest I've been able to get it. The function is very > simple. It takes a string and counts the number of non-space > characters inside of that string. > > I've been testing this code against a 460 non-space character string. > Here is the entire source, benchmarking and all: > > (def s (apply str (repeat 20 "This is a really long string"))) > > (defn count-num-chars [^String s] > (loop [s s acc 0] > (if (seq s) > (recur (rest s) (if (= (first s) \space) acc (inc acc))) > acc))) > > (println "Chars outputted:" (count-num-chars s)) > > (let [before (System/nanoTime)] > (dotimes [_ 1000] > (count-num-chars s)) > (let [after (System/nanoTime)] > (println "Time (in nanoseconds):" (/ (- after before) 1000.0 > > Running it gives me around 137343.295 nanoseconds. I've seen some Java > algorithms that could run at just under 3000 nanoseconds. > > Hide your children and hide your women; I want to see the direst, > nastiest, rawest, fastest possible implementation of this function. > > -- > 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 -- Sent from an IBM Model M, 15 August 1989. -- 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
Let's see how fast we can make this
I have a piece of code, and I'd like to see how fast it can be. (defn count-num-chars [^String s] (loop [s s acc 0] (if (seq s) (recur (rest s) (if (= (first s) \space) acc (inc acc))) acc))) This is the fastest I've been able to get it. The function is very simple. It takes a string and counts the number of non-space characters inside of that string. I've been testing this code against a 460 non-space character string. Here is the entire source, benchmarking and all: (def s (apply str (repeat 20 "This is a really long string"))) (defn count-num-chars [^String s] (loop [s s acc 0] (if (seq s) (recur (rest s) (if (= (first s) \space) acc (inc acc))) acc))) (println "Chars outputted:" (count-num-chars s)) (let [before (System/nanoTime)] (dotimes [_ 1000] (count-num-chars s)) (let [after (System/nanoTime)] (println "Time (in nanoseconds):" (/ (- after before) 1000.0 Running it gives me around 137343.295 nanoseconds. I've seen some Java algorithms that could run at just under 3000 nanoseconds. Hide your children and hide your women; I want to see the direst, nastiest, rawest, fastest possible implementation of this function. -- 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