Hacker Newsnew | past | comments | ask | show | jobs | submit | sfraser's commentslogin

I think you are right in this case - I updated my example code above to use bitwise and it is running in the same amount of time. (100,000 iterations in about 6 milliseconds)


To be clear I <3 clojure, but I'm taking the bait just for fun:

1) The chunk of Java code shows a complete program - the others show function definitions 2) The Java is written purposely to be as verbose as possible 3) The Java sends it's output to stdout, unlike the others 4) The Java code is needlessly written using generics

Things the comparison ignores: 1) The Java code is more toolable than the others 2) The Java code will outperform most of the other examples once it has been subject to Hotspot

Here's a more fair comparison, at the function level to level the playing field (and only one import needed: java.util.*):

    List trollBait() {
        return new ArrayList(){{
            for (int i : new int[]{1, 2, 3, 4}) {
                if (i % 2 == 0) add(i);
            }}};
    }
Here's why I absolutely do heart Java:

I just ran this 100,000 times in 6 milliseconds on a Core i7 920 (2.67 GHz). And I scanned it with Findbugs, and PMD, and a security vulnerability tool. And I refactored it in my IDE with crazy IntelliJ foo-jitsu. And it's more strongly typed. And it's runtime memory model is safer.


now we're talking, this is a really good response! I almost agree with all of your points, except for the performance, and only in thoroughness: a benchmark will be nice.

And for clarity: the other ones aren't function definitions, they also build a new list, like your example. The examples are meant to be run in a REPL and that's why they don't send to stdout, although it will be just another function application in most cases (but your example works in beanshell, the stand-alone java quasi-REPL, so we're ok). I think all of them can be considered a full-program in those languages: as a stand-alone chunk of code that can be compiled/interpreted and will produce an executable output, that is. And, yes, the autoboxing was the only reason I chose generics, but I tried for it to be concise, given my limited knowledge of java; the max-verbose mode would have used a Runnable or something evil to simulate a higher order function.


Thanks... my experience with clojure on the JVM is it is in general slower than optimally tuned Java code. I really can't imagine that any of the other languages you listed would easily outperform the code I have here, but maybe since the use-case is a sweet spot for functional? The person who responded to me with the F# example reported a crazy low time, and I am wondering if they have a defect in the code. I think it is possible a true functional language could make some tweaks that Java can't (like realizing the function is idempotent and caching the response instead of recalculating it). Maybe that is why the F# example was so quick - either the way it times itself is defective, or perhaps the runtime memoizes the function.

My experience with all the languages in your sampler is that their runtime performance usually lags the Java on the JVM for general purpose programming. This is not an argument not to use them - I would prefer many of them in certain use cases. But if I want a managed runtime, and have some performance critical code that I am OK with being written in an imperative language, it is hard to beat the performance of simple Java on the JVM. There has been so much tuning to Hotspot over the last decade. That's been my experience anyways.


Interesting, and yes, I am a witness of how fast proper java is; and in extreme performance cases, I guess I'd turn to java before C++ ; maybe the f# also benefits from optimizations (like tail-call optimization) and the underlying VM? (though I don't know how performant the CLR is)


You've probably seen a lot of other people's Java code. Does it typically look like what you wrote or the code on github?


You have a point... sadly most of the Java code I have seen does look like the code on github. Or worse! ;)


That's not bad, how about 0.014 milliseconds for 100,000 iterations? On a Core i5 @ 2.6 Ghz

  // Learn more about F# at http://fsharp.net
  open System

  let consume x = ()
  let start = System.Environment.TickCount

  Seq.init 100000 id
  |> Seq.iter (fun x ->  [0..4] |> List.filter (fun y -> (y % 2) = 0) |> consume ) 

  let endTime = System.Environment.TickCount
  printfn "%f milliseconds" (TimeSpan.FromTicks(int64(endTime - start)).TotalMilliseconds)

Output:

  0.014100 milliseconds
  Press any key to continue . . .
I'm sure if I added some java line noise I could get it up to 6 milliseconds. Too bad I didn't need a calendar class to figure out how to get from ticks to milliseconds. It's also really unfortunate that System.Environment.TickCount compiles down to a single assembly instruction. I was really hoping to use a factory pattern in there somewhere. Maybe some IOC containers. What good is a language if you can't write half your code in XML.


That is crazy fast... funny, but based on your response I am guessing you don't know why. What could possibly explain such a big difference? Understanding this is what separates a seasoned pro from someone throwing out trollbait comments about XML and assembly instructions.

First off, the resolution of TickCount is not less than 500 milliseconds. Are you sure you are actually timing it right? Maybe you should have used DateTime.Ticks which has a higher resolution. (seriously - I think you need to check your code)

But in any case, let's say your test is actually valid. You mentioned "Java line noise" - not really a real explanation for the difference.

So let me guess for you - maybe your F# runtime knows the function is pure and idempotent, and after running it once it probably just cached the output. So your run doesn't actually execute the filter across the list for every iteration, whereas my Java code did.

I could rewrite my Java code to return the same array over and over after it has been computed once, but it sure won't look as clean as a functional language like F#. I grant you that, and that's one of the reasons I prefer functional languages to Java.

Next time maybe put a little more thought into the response if you actually really have no idea why your program said "0.014100 milliseconds".


TickCount has 1 millisecond accuray and it's actually milliseconds, which is what tipped me off to the low numbers. It actually takes 140 milliseconds to execute. I redid the code to not use Seqs and now it's down to 15 ms.

  // Learn more about F# at http://fsharp.net
  open System

  let consume x = ()
  let start = System.Environment.TickCount
  let arr = [| 1..4 |] 
  for i = 1 to 100000 do
    arr
    |> Array.filter (fun y -> (y % 2) = 0) 
    |> consume 

  let endTime = System.Environment.TickCount
  printf "%d milliseconds" (endTime - start)


Thanks for the follow up.

I do hope to learn more about F#, I am hearing good things about it.


http://flyingfrogblog.blogspot.com/2009/07/ocaml-vs-f-burrow...

Great article about how F# can approach the speed of C with some fancy inlining.


You would still be able to run the Open JDK. There is a port for the Mac, but if I am not mistaken it uses the X Server and is not as well integrated with the graphics layer of OS X desktop. Example: http://landonf.bikemonkey.org/static/soylatte/


Hi everyone, I added the text as a comment to the image so you can read/copy it more easily.


Shucks, I did the transcript too above, at 4x zoom :-/

That will be $0.10, Sir!


I had the same thought - also note that the software powering the Squeezebox server AND the devices is open source! In fact they just flipped the player software (written in LUA) over to BSD, here's the commit:

http://svn.slimdevices.com/jive?view=revision&revision=8...

You can download nightly builds here: http://downloads.slimdevices.com/nightly/?ver=7.5

Backend is perl, and is GPL: http://en.wikipedia.org/wiki/Squeezebox_Server

The player software is written in LUA and runs well on OSX and OK on Linux (I am running the nightlies).

I have found the hardware players to be quite nice, and with iPeng on my iPhone I can control everything from anywhere: http://penguinlovesmusic.de/ipeng-the-iphone-skin-for-squeez...


I've also had an excellent experience with 3 versions of their hardware (slimp3, squeezebox2, radio).

Another pointer with a HN resonance is (note the beer bottle):

http://gigaom.com/2006/09/07/portrait-of-a-startup-slim-devi...

Of course they sold to Logitech some time ago:

http://gigaom.com/2006/10/18/slim-devices/


It seems so appropriate that this truly evil venture is headed up by someone coming from Microsoft.


Yeah, I mean, just look at all the evil Bill Gates has wrought upon the earth since he left.


I will be giving it either in April or May at the Philly Java User's Group. ping me on twitter (sfraser) for email of JUG organizer.

-Scott


This sounds really interesting. Is there any chance that you'll give it closer to the middle of the country? I'm in Milwaukee, but Chicago's just a hop skip and a jump away.


Excellent, thanks


any chance for you coming out to Hawaii?


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: