Andrey Hihlovskiy

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

Monthly Archives: January 2014

Rooty v0.0.1 is out!

Rooty v0.0.1 is out!
Simplify your multi-project #gradle setups with this plugin!
Sources and documentation available at:
https://github.com/akhikhl/rooty
Also in maven central!

Advertisements

Mavenize version 0.0.1 is out!

I release Mavenize version 0.0.1 – jar library and gradle plugin for mavenizing OSGi bundles!

Sources and documentation available at:

https://github.com/akhikhl/mavenize

Soon in maven central!

Gitbucket – your own github-like web-application without a hassle

Meet gitbucket – your own github-like web-application, requiring minimum configuration:

https://github.com/takezoe/gitbucket

Features:

  • out-of-the-box HTTP access to git repositories (in browser and from command line)
  • web-based user management
  • web-based repository management
  • issue management, pull-requests, wiki, etc.

Not yet implemented features:

  • out-of-the-box SSH support (or integration with SSH-supporting solutions like gitolite)
  • online editing

My impression: this is very interesting application that I will certainly use as soon as missing features get implemented.

gradle-onejar plugin version 0.0.5 is out!

I just released gradle-onejar plugin version 0.0.5!

The sources are available at https://github.com/akhikhl/gradle-onejar.

gradle-onejar is a gradle plugin, automating assembly of java application to a single runnable jar.

The plugin is available in maven central under coordinates “org.akhikhl.gradle-onejar:gradle-onejar:0.0.5”

It has many configuration options, described in online documentation.

Your comments and suggestions are welcome – here and at github!

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!

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/