Andrey Hihlovskiy
Professional blog on groovy, gradle, Java, Javascript and other stuff.
Monthly Archives: January 2014
Rooty v0.0.1 is out!
January 31, 2014
Posted by on 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!
Mavenize version 0.0.1 is out!
January 29, 2014
Posted by on 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
January 25, 2014
Posted by on 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!
January 23, 2014
Posted by on 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!
January 20, 2014
Posted by on I released Gretty (gradle + jetty) version 0.0.9!
New: support of JEE annotations.
https://github.com/akhikhl/gretty
Also in maven central!
ConvNetJS – Deep Learning in your browser
January 13, 2014
Posted by on 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)
January 13, 2014
Posted by on 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”
January 12, 2014
Posted by on 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 n 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 & 2 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
January 9, 2014
Posted by on 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/
Recent Comments