I've been working on a sparetime project for a few weeks and had something
mostly coded up in Java, then realized that perhaps I was trying to
re-invent the wheel so I googled for a library to do the heavy lifting for
me.
Imagine my surprise when many of my queries for xyz java library started
returning xyz javascript library.
Just for fun I decided to look at the effort involved in remaking my
prototype in Javascript using node.js and some helper libraries.
When I found that 90+ % of my prototype was available as library functions
and it was more or less a matter of gluing them together. I decided to go
ahead and just give it a try in js.
Now don't get me wrong. I'm hardly a javascript noob. I was writing
Ajax-like website helpers scripts before we ever coined the terms Comet or
Ajax. Nevertheless I've always viewed it as a tool for making shiny bits
and/or using it as a scripting language for controlling other programs. In
other words I've always seen it as being firmly as part of the view
component. I never really viewed it as something for serious computational
workloads. Until now.
I finished both prototypes to the same level. With my curiosity piqued I
decided to let them both rip on separate instances in the same AWS
availability zone, same EC2 machine types (t1.micro).
The job is just to hash words from a dictionary list (I'm making a personal
rainbow table) using a few different hashing algorithms after which I will
be doing an analysis with map reduce but neither the the map reduce nor
analysis steps are included in this part. This is just a feed generation
step.
I just wanted to test raw hashing power in this case.
I added a loop counter to the main loop and put in stopwatch function to
ensure identical runtimes.
Here are my results after 2 minutes of runtime...
Java 7 J2SE : 1,000,079
Node.js Javascript : 1,548,103
The numbers represent how many times it made it through the final loop
where it would normally have written out a csv. Thus there were several
steps. Read a fixed list, them run SHA256, Scrypt and Ripe-MD160 on each
unit. There was no output step so as to rule out filesystem access times.
This isn't meant to be a head to head comparison.
The Node.js version is (to the best of my knowledge) single threaded and
the Java version is running on a thread per core model (even though the
test box is 1.5 cores). Looking back, going with thread per core may have
gimped the Java version because of list contention, and/or context
switching penalties so I do doubt the numbers here are anything resembling
final. In fact I ran it for 5 - 10 - 15 and 30 mins as well and once JIT
kicked in and moved some stuff to metal, Java slightly matched (at 15 mins)
and slightly exceeded (at 30 mins) Javascript.
Javascript just trucked along at the same rate during similar intervals.
The point is, When the heck did Javascript become suitable for something
that's so computationally heavy? A 50% performance improvement over Java
in a short interval, especially when I have not done anything to
intentionally gimp the Java version, tells me this is not the Javascript I
used to know.
It also showed me something about my own internal biases.
I find it odd how my thinking has evolved over time.
I used to be a computer programmer who had a good/decent familiarity with a
broad range of languages and I would always try to select the best tool for
the job taking into account the cost of developer time vs cpu time.
Over the past 4 or 5 years I've been so heavy into Java (because that's
what employers want), that I think I may have evolved into a Java
programmer.
This experience has shown me that it might be time to broaden my horizons
and again embrace the "right tool for the right job" approach I used to
have, rather than the Swiss Army Chainsaw habits I've picked up from
programming in Java.
So what do you think? Have you looked at any languages for purposes you
had previously disregarded? What were your thoughts?