Andrey Hihlovskiy

Professional blog on groovy, gradle, Java, Javascript and other stuff.

Gretty version 0.0.9 is out! Long live gradle and jetty!

I released Gretty (gradle jetty) version 0.0.9!

New: support of JEE annotations.

https://github.com/akhikhl/gretty

Also in maven central!

Advertisements

Gretty 0.0.8 is out!

I released Gretty version 0.0.8!

New: support of “jetty.xml” and “jetty-env.xml”.

Gretty is gradle plugin for running web-applications under jetty 7, 8 and 9 and servlet API 2.5, 3.0.1 and 3.1.0. It greatly simplifies and accelerates web-application development by providing:

  • hot-deployment
  • war-overlays
  • java debugger support
  • jetty security realms support
  • jetty.xml and jetty-env.xml support
  • slf4j/logback support

The complete sources and documentation are available at https://github.com/akhikhl/gretty

The compiled jars are in maven central under group 'org.akhikhl.gretty'

ConvNetJS – Deep Learning in your browser

http://cs.stanford.edu/people/karpathy/convnetjs/

This is truly amazing project. Right in your browser you can start neural network and see how it learns. Source code included – excellent starting point for study and collaboration!

The most entertaining reading of all time (at least, for some)

R.M. Smullyan, “The tao is silent”. I remember reading this when I was 15. At that time I thought: “this is astonishing”. Now I add: “and deep”.

Excerpt: http://www.mit.edu/people/dpolicar/writing/prose/text/godTaoist.html

Critique on “4 more Javascript hacks to make your javascript faster”

I generally praise Nicholas Ortenzio in CSS Perverts for writing an article “4 more Javascript hacks to make your JavaScript faster”. That could be a good article, if only author would not make so many mistakes in his statements and conclusions.

update-20140113:
OK, people, thank you so much for explaining me it was a “satire”. Call it trolling, whatever. I will not sermonize or edify anyone. I truly regret my precious time I spent reading this bullsh*t and analyzing it. If it was the goal of the article’s author, he/she completely reached his/her goal.

The left of my response I leave unchanged.

Let’s parse an article step by step:

1. Get rid of those nested loops

Nested loops have a computational complexity of O(n^2). This means that if you have items, it will take n*n seconds to complete the loop.

Critique: This is true only for a special case: when nested-loop is applied to the same collection or to multidimensional array of uniform dimensions. There are many cases not falling into this category.

// because this loop is nested, it can
// take up to 100 seconds to complete
for (var i=0; i<10; i+=1) {
 for (var j=0; j<10; j+=1) {
 console.log(i, j);
 }
}
// better
for (var i=0, j=0; i<10 && j<10; j++, i=(j==10)?i+1:i,j=(j==10)?j=0:j) {
 console.log(i, j);
}
//best
for (var i=0, j=0; i<10 && j<10; j++, i=(j==10)?i+1:i,j=(j==10)?j=0:j, console.log(i, j)) { }

Critique: the statement in the first comment is plainly wrong. The loop takes around 10 milliseconds in Firefox on average computer. The slowest part is, of course, console.log (not the loop mechanism itself). As soon as console.log is replaced to, say, arithmetical operation, the loop performs under 1 millisecond. Since testing at 1 or 10 milliseconds does not give any reliable results, the test should be improved by increasing count to, say, 100 or 1000. At such counts the results are as follows:

// this loop finishes on average in 860 milliseconds
for (var i=0; i<100; i+=1) {
 for (var j=0; j<100; j+=1) {
   console.log(i, j);
 }
}
// this loop finishes on average in 940 milliseconds
for (var i=0, j=0; i<100 && j<100; j++, i=(j==100)?i+1:i,j=(j==100)?j=0:j) {
 console.log(i, j)
}
// this loop finishes on average in 960 milliseconds
for (var i=0, j=0; i<100 && j<100; j++, i=(j==100)?i+1:i,j=(j==100)?j=0:j, console.log(i, j) ) { }

Conclusion: results are actually getting worse, when the one tries to “optimize” loops that way.

To make results more reliable, lets replace calls to console.log by arithmetic and increase loop count to 1000:

// this loop finishes on average in 680 milliseconds
var z
for (var i=0; i<1000; i+=1) {
 for (var j=0; j<1000; j+=1) {
   z = i * j
 }
}
// this loop finishes on average in 1540 milliseconds
var z
for (var i=0, j=0; i<1000 && j<1000; j++, i=(j==1000)?i+1:i,j=(j==1000)?j=0:j) {
 z = i * j
}
// this loop finishes on average in 1560 milliseconds
var z
for (var i=0, j=0; i<1000 && j<1000; j++, i=(j==1000)?i+1:i,j=(j==1000)?j=0:j, z = i * j) { }

Again, we see – attempts to “optimize” a javascript loop only make things worse!

2. Bit shift instead of multiply

Did you know that at a molecular level, computers can only add (and they can just barely do that) Computers “multiply” by using a combination of expensive logarithmic look up tables and extremely lucky guesses. Since CPU’s are so fast, they can make dozens of guesses per second until they come up with the right answer.

Instead of multiplying, use the bit shift operation. it looks a little more complex, but once you get the hang of it, it’s pretty simple. The formula to multiply x * y is simply x << (y-1)

// multiply by 1
[1,2,3,4].forEach(function(n){ return n<<0; }) // 1,2,3,4
// multiply by 2
[1,2,3,4].forEach(function(n){ return n<<1; }) // 2,4,6,8
// multiply by 3
[1,2,3,4].forEach(function(n){ return n<<2; }) // 3,6,9,12
// etc

Regarding the “molecular level”, see “Instruction Latencies in Assembly Code for 64-Bit Intel® Architecture”   and the discussion on stackoverflow. Brief summary: modern CPUs implement floating-point multiplication as a single instruction, which is not slow at all.

“Instead of multiplying, use the bit shift operation” – wrong!

First mistake the author made is that he did not even test his own code – in its current form it does nothing. “forEach” function does not change an array, it simply calls the specified function for each member of the array. To make it work, the one needs to replace “forEach” with “map”.
And even when we fix and run the code, it returns wrong results:

console.log(JSON.stringify([1,2,3,4].map(function(n){ return n<<2; }))) // 3,6,9,12
// actually it prints [4,8,12,16] !

3. Round real numbers before multiplying them

The trick above is a great time save for integers. But it doesn’t work for so-called “floating point” numbers (FP for short). In this case, computers really SUPER slow. A Multiplication operation (known as a MUX in programming terms) using the two values, 9.52434123 takes forever (in milliseconds) to compute. You can’t always avoid FP MUX OPs, but there is a trick to speed them up if you can sacrifice a bit of precision. Simply round the number using the toFixed operation.

// pretty  much the same thing but the second line
// is much faster
9.52434123 * 2
9.52434123.toFixed(2) * 2

Wrong! When the abovementioned code is benchmarked, second variant is actually slower:

var x = 9.52434123;
var y = 2;
// this loop finishes on average in 7800 milliseconds
for(var i = 0; i < 10000000; i++)
  z = x * y;
var x = 9.52434123;
var y = 2;
// this loop finishes on average in 14100 milliseconds
for(var i = 0; i < 10000000; i++)
  z = x.toFixed(2) * y;

Again, modern computers are not super-slow on floating-point operations. Before making such statement, the one needs to read at least some literature and to do at least some benchmarking.

CES-2014: Project Christine

There’s something far more interesting than pebble watch or talking fridge at CES-2014: a modular computer represented by company Razer:
http://www.gamespot.com/videos/checking-out-razer-s-modular-pc-project-christine-/2300-6416753/

Gretty 0.0.7 is out!

Gretty 0.0.7 (gradle jetty plugin) is out! New: logback re-init on hot-deployment.

https://github.com/akhikhl/gretty

Gretty 0.0.6 is out!

gretty 0.0.6 (gradle plugin) is out!
News: support of jetty 7/8/9, servlet-api 2.5/3.0.1/3.1.0.
https://github.com/akhikhl/gretty
Merry Christmas! 🙂

Simple arithmetic: snail climbing a pole

A snail climbs all the way up a pole 12m high. It climbs 3m each day but slides down 2m each night. How long will it take the snail to reach the top of the pole?

GVM – tool for managing groovy/gradle versions

Just discovered GVM – Groovy enVironment Manager ( http://gvmtool.net/ )
First impression: it’s like apt-get, but for groovy-based frameworks. Second impression: support of multiple versions is very useful thing.
Will use it at home and in office to automate installation of groovy-related stuff.