My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label Google. Show all posts
Showing posts with label Google. Show all posts

Wednesday, May 25, 2011

JavaScript Builder from Falsy Values

Update: uglify-js as third option


Thanks to @kitgoncharov JSBuilder now includes the option to run uglify-js through Rhino ... still cross platform, a builder for any taste.




as promised during my workshop, I have created a Google Code Project with the builder used to demonstrate most advanced and common techniques to make a library, application, snippet, small and fast.

What Is JSBuilder

It's a truly simple Python module based over a certain hierarchy able to combine multiple files and produce a minified version of the application.
A similar approach has been used since ages with jQuery, and I am pretty sure there are tons of builders out there able to do similar task.
I personally created ages ago a similar project compatible with all windows platform.
However, that project was missing the possibility to put everything together, preserve some piece of code if necessary, replace some string runtime, and produce if necessary different outputs through the simplified module approach.
Here a build.py file example, the same you can find in the repository.

# JSBuilder example

# project name (from the root folder)
copyright = '(C) WebReflection JSBuilder from Falsy Values'
max_js = 'build/max.js'
min_js = 'build/min.js'

# file list (from the root/src folder)
files = [
"intro.js", #beginning of the closure
"variables.js", #local scope variables
"main.js", #some application logic
"functions.js", #functions declaration
"debug.js", #something useful or evil to debug
"outro.js" #end of the closure
]

# execute the task
import JSBuilder
JSBuilder.compile(
copyright,
max_js,
min_js,
files,
# optional list of serches
[ #mustaches in comments, hell yeah!
'/*{namespace}*/'
],
# with relative optional list of replaces
[
'var ' #produce var MyLib = ...

# it could be 'this.'
# this.MyLib = ...

# it could be 'my.personal.stuff.'
# my.personal.stuff.MyLib = ...
]
)

# let me read the result ...
import time
time.sleep(2)


Why Python

First of all the version is the 2.6 or higher but not compatible (yet) with version 3+.
Python to me is a sort of server side lingua-franca and it is missing by default only on Windows platform.
I would say the same about Java, with the slightly difference that in Python we don't need to create a class to perform a simple task as the one performed by JSBuilder.
If Python is not present in our system, we can easily find the installer in the python.org website while the build.py example code should be easy to understand even for non programmers.

Java As Well

Both YUICompressor and Google Closure Compiler come with a jar package which is a classic build out of one or more Java files. JSBuilder uses Java as well in order to call one compiler or another one with proper arguments and in a cross platform way so ... just in case you do not have Java installed, here the link to download what we need.

The Current Folder Structure

projectFolder
build
builder
src
Above structure is exactly the same you can find in the repository but don't worry, as you can spot in the build.py file we are free to change destination folders or paths without problems.
JSBuilder assumes in any case relative paths from the root of the application but if you really need a different structure feel free to replace the string '../' with the one you prefer ... it is an easily replaceable part of the script, just find and replace and that's it.

Multiple Projects

The build.py file is just an example but obviously we can create as many examples as we want, even inside the build.py file itself, changing just the part to replace, destination files, and/or copyright if necessary.
JSBuilder should be suitable for all sort of cases ... at least for all cases I have been facing since I have started with JavaScript (10 years of cases, I hope it's enough)

The Concept Behind

As you can see there are different sources behind the scene and the application is distributed across multiple files.
While this concept may be not that familiar or weird, this has been used by jQuery library since ever and even if teams may think it's not easy to maintain such distributed code, a proper structure following some standard could be more than we need to make everything simple.
As example, the file called variables.js contains all local scope variables reused inside other files as well.
Of course if a variable has a meaning for more than a file, it makes perfect sense to put it in the precedent one, even as undefined variables, to eventually assign it later.

Closure Compiler VS YUICompressor

If you checkout the whole project and you try to build once with YUI and once with Closure Compiler, simply swapping comment on line 63 of JSBuilder.py file, you will realize these minifiers are able to produce a completely different output.
I leave you read all comments inside JSBuilder.py in order to understand what happens there exactly, and I hope you will realize there is even more than zou have imagined.

Debugging Code

Sometimes you may need a portion of code for debugging purpose, and the not minified version of the file is the only place where it should be.
When it comes to debug, we would like to be able to export outside private variables or functions, still understanding their original names rather than the minified one.
The debug.js files as example is able to modify internal variables thanks to evil eval function.
This piece of code is surrounded by this comment:

//^
... the debug/evil code ...
//$

If you are familiar with regular expressions you can spot that ^ as "start evil code" and $ as "end evil code" have semantic meaning ... and this is what will never be included in the final minified version of our app.

Give It A Try

I hope those present in my Falsy Values workshops got the advantages a build system could bring on our daily basis work but I have written as many comments as possible to let you understand what is going on, how does it work, and why this simple script is freaking cool and it could potentially become our favorite build system.

What's Next

In my personal projects I have included an extra line at the end of the build.py able to create, per each build, documentation.
This kinda helps me to do not forget I have to document new or modified stuff, plus it gives me extra hints if some documentation has been lazily copied and pasted rather than being rewritten ... well, I honestly don't really like jsDocToolkit since JavaScript syntax has nothing to do with Java one but I agree is, at least, a tool flexible enough and still widely adopted and/or extended so ... if you all agree, I will put the magic documentation part there inside a build-with-doc.py file example.

Monday, November 09, 2009

Google Closure ? I'm Not Impressed

We all know that Google is synonym of performances, simplicity, and again performances. A search engine that uses a truncated body for a not valid W3 markup should be the most bytes and performances maniac in the current web era, isn't it?
Well, Google Closure Tools has been a negative surprise, at least this is what I can tell about it after a first quick review.

Closure Compiler


It's since ages I am wondering what kind of tool Big G is using to produce their scripts and finally we got the answer: Closure Compiler ... ooooh yeah!
Packer, YUIC, it does not matter, when Google needs something, it creates something. This is almost intrinsic, as developers, in our DNA: we spot some interesting concept? We rewrite it from the scratch pretending we are doing it better!
This is not the case, or better, something could go terribly wrong!

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// ==/ClosureCompiler==

(function(){
"use strict";
this.myLib = this.myLib || {};
}).call(this);

myLib.test = 123;

The produced output:

(function(){this.a=this.a||{}}).call(this);myLib.test=123;

And 2 warnings:

JSC_USELESS_CODE: Suspicious code. Is there a missing '+' on the previous line? at line 2 character 4
"use strict";
^
JSC_USED_GLOBAL_THIS: dangerous use of the global this object at line 3 character 4
this.myLib = this.myLib || {};
^

Excuse Me?
The sophisticated compiler is able to understand the "use strict" ES5 activation statement and the fact we are passing the global object as this reference in the closure. It does not matter, as showed in the produced code the result will be a broken library, thanks to its missed name, magically transformed into "a".
Advanced Optimization Could Fail to both give us right suggestions and fix or optimize the code, since in that case, as example, this.a won't perform anyhow faster than original this.myLib.
Advanced Optimization parameter could also be dangerous for lazy loaded libraries.
We need to be extremely careful with this option and, as result, rather than a Compiler, we will deal with a "code messer" where hard debug will become automatically the hardest ever.
Read Carefully This Page if you are planning to use this option because under the flag "best ratio" and "removed dead code" we could have massive surprises in the middle of the application.

As summary, SIMPLE_OPTIMIZATIONS as compilation_level directive is so far the recommended one, but at the same time it won't offer that different ratio compared against YUI Compressor or Dean's Packer (NO base62) produced outputs while ADVANCED_OPTIMIZATIONS could be tested for single stand alone files hoping these won't break the global namespace via renamed variables.
In this case a JavaScript closure, the real one, is an absolute must!

Closure Library


This is another part, not strictly related with the Compiler, but apparently able to work with it. The Closure Library is a wide namespace loads of core features and a cross browser User Interface. I have to admit this library is a massive piece of work, but techniques used to make it happen are often hilarious.
First of all, this is the first time I read protected variables called with an underscore at the end, rather than as first char:

// normal code
function Constructor(){
this._protected = [];
};

// Closure Library Creativity
function Constructor(){
this.protected_ = [];
};

Why On Earth? Python style a part, where the underscore has a concrete meaning, the technique to use underscore as first character has a reason to exists.

function copyOnlyPublic(o){
var $o = {}, k;
for(k in o){
if(k.charAt() !== "_")
$o[k] = o[k]
;
};
return $o;
};


var myC = new Constructor;
var $myC = copyOnlyPublic(myC);

No Way! To make the style "creative" the charAt method with optional 0 as argument needs to become:

if(k.charAt(k.length - 1) !== "_")

Is this what we would expect from the performances king? I don't think so.
Is this faster to read at least for human eyes? Neither!
Gotchas are everywhere in the library ... the most redundant stuff I've ever seen is the array namespace!

goog.array.indexOf = function(arr, obj, opt_fromIndex) {
if (arr.indexOf) {
return arr.indexOf(obj, opt_fromIndex);
}
if (Array.indexOf) {
return Array.indexOf(arr, obj, opt_fromIndex);
}

var fromIndex = opt_fromIndex == null ?
0 : (opt_fromIndex < 0 ?
Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex);
for (var i = fromIndex; i < arr.length; i++) {
if (i in arr && arr[i] === obj)
return i;
}
return -1;
};

OMG, I can't believe performances matter only for a missed body tag in the layout ... it cannot be real, can it?
What we have there? 1 to 2 possibly missed checks for each call (IE) and everything just to emulate the native Array.indexOf which is present in basically every browser except truly old or Internet Explorer?

goog.array.indexOf = Array.indexOf || function(arr, obj, opt_fromIndex) {
var fromIndex = opt_fromIndex == null ?
0 : (opt_fromIndex < 0 ?
Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex);
for (var i = fromIndex; i < arr.length; i++) {
if (i in arr && arr[i] === obj)
return i;
}
return -1;
};

Array.indexOf is used as fallback if for some unknown reason (and browser...) an Array has not indexOf but Array.indexOf is present ... well, if we can trust that case is there any valid reason to create a performance gap like that for almost every method?
forEach, lastIndexOf, every JavaScript 1.6 or greater emulated method contains redundant checks performed for each call ... where is the performance maniac here?
The feeling is that this library has been created by some Java guy, probably extremely skilled with Java, but definitively not that clever with JavaScript programming style. Google if you need skilled JS developers there are hundreds of us out there. What I mean is that it does not matter if a minifier is able to remove dead code because dead code should not be there at all, isn't it?

// WebReflection Suggestion
goog.array.clone = (function(slice){
try{slice.call(document.childNodes)}catch(e){
slice = function(){
var rv = [];
if(this instanceof Object)
// suitable for arguments
// and every other ArrayLike instance
return rv.slice.call(this)
;
for (var i = 0, len = this.length; i < len; ++i)
rv[i] = this[i]
;
return rv;
};
};
return function(arr){
return slice.call(arr);
};
})(Array.prototype.slice);

Above suggested snippet is based on Features Detection, a technique apparently completely discarded in those files I've read in this library.

Features Detection Cons

  • performed runtime, few milliseconds before the library or function is ready to use


Features Detection Pros

  • performed once, and never again for the entire session
  • best performances, browser independent and browser focused at the same time
  • being usually based over most recent standards, features detections could cost a bit more only for deprecated, obsolete, or truly old browsers


Moreover!

If the problem is the wasted millisecond to perform a feature detection, we can always fallback into lazy feature detection.
I agree that web performances are more about download time and round trip, but if Google has V8 as engine monster, do we agree that better JavaScript practices could make even V8 faster?

Lack Of Creativity

Even if this library uses some weird practice, most logical and common techniques to speed up execution and reduce code are often not considered. As example, this is just one method we can find in the crypt file:

goog.crypt.byteArrayToString = function(array) {
var output = [];
for (var i = 0; i < array.length; i++) {
output[i] = String.fromCharCode(array[i]);
}
return output.join('');
};

Oh Really? So now a JavaScript developer should create a function which accept an array in order to create another array to populate over a loop and a global method call to perform a join at the end? That's weird, I thought that method could have been written in this way:

// WebReflection Suggestion
goog.crypt.byteArrayToString = function(array) {
return String.fromCharCode.apply(null, array);
};

... but maybe it's just me that noob that I cannot spot the difference except better performances over less code ... please enlighten me!

Closure Library, The Good Part

Is massive, for basically each file there is a test case so it is robust. For sure as we have seen before, this is not the fastest general purpose library we could find in the net, something I was expecting from Big G, but hey ... we cannot blame the excellent work done so far, can we?

Closure Templates

Well, here I am almost without a word ... I mean, the number 1 search engine able to create monster pages via JavaScript templates? I do hope those files will be performed everywhere but a web page and runtime, 'cause with incoming HTML5 I feel horrified thinking about a new web loads of document.write and nothing else. Where is the semantic? Where is the logic applied before and not during execution? Where are best practices? Looking at examples even V8CGI project is not able to perform that code ... what is that, exactly? And WHY???
The only thing I do like there is the definition file, something simple, clever, easy to parse, exactly the opposite of its implementation via JavaScript: please avoid it!

Closure Conclusion

No this is not another piece of the puzzle, just the end of this post. I've been probably too aggressive and it's only thanks to Google decision that I can write a post like this: Open Source is the key, or your libraries, operating systems, whatever, will be always behind 'cause developers able to help you are not only in your team.
I was expecting excellent ideas, new killer techniques unknown for everybody else, what I have found is "yet another toolkit". I am always up to contribute so if interested put my name in the committers list, I have already lot of stuff to optimize because a Compiler, whatever it does, cannot create a better code, it can simply try to make a bit better and shorter the existent one: never delegate skills to a machine until these will be able to take decisions for us!

Wednesday, September 23, 2009

Google Chrome Frame - A First Look

In one single day the news about Google Chrome Frame has reached, I suppose, every web related company or developer. As posted before, I hope this plug-in will be adopted soon throwing away every other plug-in "record", thanks to its target: the most used, discussed, slow, and not standard, casa Microsoft default browser, Internet Explorer.
I have spent part of my precedent night sleeping testing this little revolution from Big G. and here there are first suggestions, impressions, results.

The Correct Way To Set Chrome Frame

The Google Getting Started guide is a good lecture, but it is not enough.
The Making Your Pages Work with Google Chrome Frame is incomplete, and I will tell you why.
First of all, we need to understand that Chrome is a Runtime Embedded Browser plug-in, not a tag related one then, as Adobe Flash Player is.
Writing something like:
Just add this tag to the top of the page: That's it!
is confusing and not that detailed info.
A meta tag is normally placed in the header one, top of the page, but as soon as developers read about "that's it" most of them tried to add via JavaScript this meta tag to switch engine: this is wrong.
We cannot mess up IE default Trident engine with a completely different one as WebKit via Chrome Frame is. Different are also variables, if any, globals, if any, render itself, and the best case scenario is that everything will break up!
As summary, runtime browser switch is not truly a good practice, for both main page, or iframes, since the Chrome Frame nature is to change the entire browsed content and since it does not make sense to have such hybrid, non-sense, configuration between JScript and V8, Trident and WebKit.
Accordingly, the best way to activate Chrome Frame is to put in the head tag, top of the page, and before whatever JavaScript action, the meta.

<!DOCTYPE html>
<html>
<head>
<title>Google Chrome Frame</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
... the rest of the page, scripts, css, whatever

That is still not it!

Detecting Google Chrome Frame and Prompting to Install

One more time, we need to thanks Google for all this effort but suggested solution is not ideal! (quick update: Alex Russel agrees, so the page is hpefully gonna change soon).
Chrome Frame is, so far, an Internet Explorer related plug-in which means that the external script will not do anything interesting with every other browser such Firefox, Opera, Safari, or Chrome.
Google truncates web pages (body tag) to make things as fast as possible but it is suggesting us a "slowdown without reasons" practice.
The best way to suggest Chrome Frame is to put that external script in a conditional comment:

<!DOCTYPE html>
<html>
<head>
<title>Google Chrome Frame</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<!--[if IE]><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script><![endif]-->
</head>
<body>
</body>
<script type="text/javascript">
document.body.appendChild(
document.createTextNode(navigator.userAgent)
);
</script>
</html>

If for some reason we are worried about how to know if IE supports the plug-in, all we need to do is this:

var cf = (function(i,ua){
return i<ua.indexOf("chromeframe")||i<ua.indexOf("x-clock")
})(-1,navigator.userAgent.toLowerCase());
// cf is true when plug-in is installed


Do We Truly Need To Know?

I think IE support cannot disappear today, I wish it would, but that's not gonna happen. If we develop a cross-browser Web application/site is quite useless to understand if we are using the plug in or not, 'cause if Google Chrome will be supported, special features detections a part, the website will simply looks exactly as it looks in Chrome.
I cannot spot a single valid reason, except the Install Prompt for IE, to include that file but my crystal ball says that Chrome Frame is planning to be installed as plug-in in other browsers as well in a not that far future ... so one day maybe it will make sense to remove that script from conditional comments.

Server Side Chrome Activation ?

Not yet, apparently an header in the server with chrome=1 value is useless. I hope this is a temporary issue 'cause to avoid switch delay once Trident has been already started, the server side header could be the best solution. On the other hand, being Chrome a Trident plug-in, I think Trident needs to start before the plug-in can be activated ... uhm, hell problem!

// this won't have effect so far ...
header('X-UA-Compatible: Chrome=1', true);

Update
To understand if the browser will be render the page via Chrome Frame we can use this snippet as example:

<?php
$userAgent = $_SERVER['HTTP_USER_AGENT'];
if(
strpos($userAgent, 'chromeframe') !== false
) {
// your cool standard layout for Chrome
} else {
// your crappy IE dedicated one
}
?>


My First Impression

Enabling runtime Chrome Frame via url, cf: as url prefix, I have tested Taskspeed and many others benchmarks realizing that if I had used Google Chrome the result would have been exactly the same.
The only difference is the little delay, not that little with extremely old hardware, when the meta tag is interpreted and the switch activated runtime, specially the first time.
Chrome Frame is in any case 100% WebKit and Chrome. IE features, included conditional comments, for both layout or script, attachEvent and friends or CSS expressions, are not supported.
While features such V8 multi tab threading is supported ... again, 100% Chrome.

What's Next ?

I am prety much sure the reason this plug-in is not stable is the native OS integration nature of Internet Exploer.
Talking about IE8 we have Accelerators and other specific stuff that will probably not work with this plug-in, but personally I have never used them.
In the Jurassic IE6 case the Operating System dependency is more than hard, and so far it is the most problematic browser but right now I have never encountered a single problem with this plug-in and to make it stable as soon as possible we all need to install it and test it in every single page. This procedure will help Chromium team to better and faster understand possible troubles, if any, so let's contribute: in the worst case scenario we'll have a better Web experience thanks to Chrome overall stunning performances, standards and HTML5 support.

P.S. the Developer console in IE8 should be activatd before the switch, and not after, otherwise with this version it won't work!

Tuesday, September 22, 2009

Web Terminator Salvation - Google Chrome Frame

Google Chrome Frame Bookmark, if you are surfing for whatever reason in IE, right click in precedent link, add to favorite and save as: FINALLY THE WEB, or simply copy this code and past in the website url you are surfing with IE

// corrected via kangax
javascript:void(location.href='cf:'+location.href));



It's the beginning of a Web Revolution, it's the dream of every Web developer, it's the annihilation of the most slow, problematic, non-standard, engine ever: the whatever version inside Internet Explorer!

It's the "Say Fucking What? Buggy Flash Player Yes For Ages And Chrome Frame No?" era, it's something I've been trying for ages without that direct switch, provided by this plug-in, able to forget Internet Explorer except its frame (weird choice about the name though, Google) ... it's the new stats where IE could increase again it's market share who fuckin' care as long as we can finally develop real web applications, is the no more need to wait that pachyderm libraries development ... is that ...

... uh wait, now we have another IE scenario to test ...

Thursday, May 21, 2009

google caja, what's wrong with "new" ?

In JavaScript we mainly have two type of variables:

  • primitives (string, number, boolean, null or undefined)

  • object related (Array, Object, Function, unknown for IE)


Due to this difference, a primitive string and a new String are two different worlds:

var s1 = "abc";
var s2 = new String("abc");

s1 instanceof String; // false
s2 instanceof String; // true


The nature of primitive constructor is to return a typeof constructor, but if we use new in front of the same constructor, it will obviously return an instance of that constructor.

This is the nature of javascript, summarized in this snippet:

function I1(){
return 1;
};

function I2(){};

var i1 = new I1();
var i2 = new I2();

In both cases, o1 and i2 will be respectively an instanceof I1, and I2.
In few words, if a function is caled via new, the assigned value will be an instance o the constructor itself or, if it returns an instanceof Something, the instanceof something value.

function I3(){
return new I2();
};
var iPretendsToBe3 = new I3();

iPretendsToBe3 instanceof I3; // false
iPretendsToBe3 instanceof I2; // true



The same happens with Array, Function, and Object constructors.
These kind of variables are considered objects, for the simple reason you can add runtime a property, without losing it:

var s = "abc";
var o = Object("abc"); // returns a new String

s.test = true;
o.test = true;

s.test; // undefined
o.test; // true


When we use the Object function, we will obtain an object, instanceof passed argument.
Indeed, using latest example, o instanceof String will be true.

If A Function Returns An Instance Of Something, "new" Is Redundant


While if a function returns a primitive value (string, number, boolean, undefined, unknown for IE) this value will be simply lost the moment we will use new in front of that function.

function sum(a, b){
return a + b;
};
var o = new sum();

o instanceof sum; // true

Obviously, if we call sum without the keyword "new", the function will return the sum of argument a plus argument b.

Due to this duality JavaScript functions feature, when we perform a new Array, Object, or Function, we are doing something a bit redundant, because the constructor itself will always return an instance of called constructor.

Array() instanceof Array; //true
new Array() instanceof Array; //true

Function() instanceof Function; //true
new Function() instanceof Function; //true


In the specific Function case, it is like thie scenario:

function Test(){
return function anonymous(){};
};

var f1 = Test();
var f2 = new Test();


In both cases, new or not new, the returned instance wlll be the anonymous function, which has priority over the new keyword.
Accordingly, f2 will be virtually an instanceof Test constructor between the call and the return anonymous space, something completely useless.

In my good old ActionScript memories, there were cases where the usage of Array() was not suggested because using new Array() you could have created more Arrays (I am talking about thousands of iteraction and AS1 or AS2).
Well, unless somebody demonstrate that JavaScript engines are that buggy, there is not a single reason to prefer new Function (same is for new Object and new Array) over the simple native function call.

All this post is about an interesting one opened in jQuery developer list, where at the end of the day, jQuery had to implement a common mistake/bad practice.

As summary, google-caja, please revisit some spec because this one, as example, does not make much sense :(

Wednesday, April 22, 2009

Internet Explorer with V8 Engine :: A Partial Reality

Update now it works with Internet Explorer 7 and 8 with O3D plug-in enabled.

Today, via ajaxian, I discovered the new Google O3D project and as a nerd first, and a developer after, I instantly read the API.
Few seconds and I spot this: Use the V8 engine

OK, OK, whatever code you read there will not instantly work ... you have to understand the library and how to retrieve the dreamed eval function to make JavaScript execution possible inside the extremely fast V8 engine.

Obviously V8 integration is great with FireFox and other browsers, but a bit different in Internet Explorer.

This limitation is about the DOM manipulation, something that would make IE a good browser, but everything else, executed via V8 engine and without browser engine references, will perform 5 to 100 time faster.

Function creations, optimized loops, numbers, string manupulation, etc etc ... if we could use a little plugin to fully integrate V8 inside Explorer, we could all forget nowadays benchmark because it will perform better than many other browsers!

Bearing in mind the relationship between V8 variables, different 100% from JScript vars, and latter variables, we can delegate computational tasks to this engine makin IE fast as it has never (and will probably never) been!

What I have so far, is just a poor example about V8 inside IE possibilities, a page that does not work if you do not have V8 inside Exlorer and you do not enable its usage everywhere.

Write a loop like this in the textarea:

for(var a = [], i = 0; i < 500000; ++i)
a[i] = Math.random();

and switching between default and V8 you can read that the difference is about 5 times slower with the default Internet Explorer JavaScript engine, and Google V8.

Still, so far what I can spot as pros and cons is this:
Pros

  • mathematical operations up to 100 times faster

  • computational functions speed up

  • common AI patterns (AStar) finally usable in the web

  • games, chess, cards, whatever involves logic, speed up



Cons

  • even if you assign a V8 Array.prototype.forEach to native Array.prototype.forEach, the plugin cannot solve engine related dependencies problems ... so it will be simply slower, much slower, because of the data interchange between the method executed externally, and the original engine

  • DOM is not integrated, V8 in IE does not understand nodes so no way to speed up common libraries or add prototypes to native HTMLElement constructor

  • last, but not least, with my laptop I cannot even test the example page I posted before because the JS is not that perfect (Google guys, makeClients accept an id but you check .id === "o3d" in the loop ... does it make any sense?) and my card apparently does not support OpenGL or whatever library the o3d plugin requires



As Summary


This was just a quick post and an experiment which in my opinion is already god enough. I have a vision, about Internet Explorer 8.1 ... those guys created an April fool that is everything but not a fool. Come on Microsoft, let others replace your old, problematic, slow, JScript engine, and let us developers be free to create Web Applications as we would like to do ... please give to Google whatever they need to make V8 IE integartion possible, and let us dream about a not that far possible Web future!

Friday, February 06, 2009

Another experiment inspired by Google Buttons

I found this post from Ajaxian extremely interesting, and I decided to try to create a better version, if it is possible, of Google Buttons 3.1

The result is not perfect, still alpha, and just for fun, but compatibility seems to be great while multiple buttons visualizations (horizontal or vertical) is extremely simple: write links beside each other, or add a couple of rules for vertical version.



States are hover, active, selected, represented via JavaScript events (onmouseover, onmousedown, onmouseup).
As I said this is just an experiment, but I think as is it is not that bad ... maybeI am wrong :D

Tuesday, September 02, 2008

Google Chrome Fix

Update 2008/09/04
I have created a new version that should be able to recognise the correct Google directory in every supported windows, and not only English version.

Please do not hesitate to tell me if the created link for No Sandbox Option is not creating it properly, thank you.

Google Chrome Fix Multi Language OS
-----------------------

I successfully tested the new browser in my laptop, while today I had some headache at work.

This is the reason I created in few minutes a simple Windows Application that let you choose which option you want to solve crashes during Google Chrome startup:

The application failed to initialize properly (0x00000005). Press Ok to terminate application.


Please note that the registry fix option changes a key that should solve Symantec problems, but it is not clear if this key could change security level for those PC that use Symantec end point protection, or similar softwares.

In every other case, the GUI create a link to launch Chrome without multiple sandbox, and if I am not wrong, it should mean that multi tab will not be multi thread.

Here you can find the project page, where there is a download section and an executable file.

Thanks to AutoIt developers, and ~d-bliss for the icon.

Enjoy :)

Sunday, July 27, 2008

Google Code Jam: Mousetrap in 4 languages - GAME OVER

First of all, I would like to thank the Google team for Code Jam opportunity, and its organization: AMAZING!

Yesterday I have lost my Round without a single commit.
This time I have not excuses, it was simply my fault.
I did not understand properly first two problems, or better, expected results, but I was sure the reason was my poor English knowledge, and I wouldn't be silly, asking silly questions (some question was silly enough, so, next time, I'll be less shy than this time).

Accordingly, since Code Jam is a challenge, I chose to solve the most difficult problem, the Mousetrap. First of all, because the problem, and the expected result, was so simple to understand, secondly, because it was the best one for points :geek:

Problem Analysis


Ok, we had 2 hours to analyse the problem, to find the best solution, and to commit results, and this time I did not even download the test, because I would like to be sure that my solution was good enough to solve the problem.

Count positions ... no, don't do it, count movements, no, do not count at all!


My first 3 versions of Mousetrap were so tricky, that no one worked as expected :D
After about one hour trying to find the perfect algorithm to know where each card has to be during the game, I realized that I was trying to solve them in a complex way (a sort of home made equation), and without results, instead of simply think exactly what was going on in the deck during the game.
Anyway, I wasn't able to finish the code, specially because my "perfect solution" was trying to destroy my CPU! So, honestly, for my brain and my knowledge, time was not enough to complete that task.

Brainstorming


My approach was simple: create the perfect deck!
Once we have a perfect deck, find positions is something extremely simple, since each number is, at the begin, a deck index itself minus 1 (i.e. 1,2,3,4,5 as indexes: 0,1,2,3,4), so once you have moved each card over indexes, you can find card positions simply using created array.

card = "5"
result[(int)card - 1] = ... moved card.

At this point, we need to create the deck, and nothing else.
The first version was based on movements, and removed cards, to know the position of each card in that index. A sort of tracing, using a simple function like this one:

function movements(card){
return 0 < card ? card + movements(card - 1) : 0;
}

In this way we can know that when we are looking for card N, we have removed N-1 cards beforfe, and moved movments(N-1) time other cards.
This was probably the right direction, but it was exponential, and results completely wrong ... and snce we had 2 hours, I though to change strategy.

The most simple, logical, and expensive solution at all


Try to imagine we have 5 cards, so the deck will be: 1,2,3,4,5
The sequence, during the game, will be this one:

12345 [card = 1, pos 1]
2345 // remove one, and count fr next card
3452 [card = 2, pos 3]
452 // remove one, and count for next card
524 // counting ...
245 [card = 3, pos 2]
45 // remove one ...
54 // counting ...
45 // counting ...
54 [card = 4, pos 5]
4 // counting ...
4 // counting ...
4 // counting ...
4 // counting ...
4 [card = 5, pos 4]

Above operation is exponential as well, but in my mind it was the best one ever to be sure about the result. That is why I started to play the game!

Mousetrap with JavaScript


When I realized that in that simple way the code was truly slim, I though about 2 possibilities: 1 - I am a f#*@in genius, 2 - There is something wrong, it cannot be that simple, I am an idiot!
Once I have created the code:

// JavaScript
function perfectDeck(cards){
for(var
deck = range(cards),
result = range(cards),
count = 0,
i = 0;
i < cards; i++
){
while(count++ !== i)
deck.push(deck.shift()); // move cards
result[deck.shift()] = count;// remove one
count = 0; // start counter again
};
return result;
};

// JavaScript Extra
function range(length){ // return an array with 1:1 index/value integers
for(var i = 0, result = new Array(length); i < length; i++)
result[i] = i;
return result;
};

// example
alert(perfectDeck(5))
// 1,3,2,5,4

I did some test, and I checked results in my minds, and those were expected. Well done?

Mousetrap, PHP implementation


At this point, I need to parse the input file, and to produce an output file.
Since the code was extremely simple, I have though about PHP, to be able to read the input, and produce the output to upload.

function perfectDeck($cards){
for(
$deck = range(0, $cards - 1),
$result = range(0, $cards - 1),
$count = 0,
$i = 0;
$i < $cards; $i++
){
while($count++ !== $i)
array_push($deck, array_shift($deck));
$result[array_shift($deck)] = $count;
$count = 0;
}
return $result;
}

Damn it, literally 1 minute to create my PHP perfectDeck version.
Now, lets do some test to be sure everything is correct ... ok, that's correct.
At this time, I read the problem again, and I realized that I was debugging with 3, 4, 5 or 7 cards, thinking that a deck could not have more than 15 cards (poker addicted!) ... well, things are a bit different, since limits are clear, and we are talking about a maximum of 5000 cards, and for the small input!!! :o

Python version


Since trying to generate the perfect deck with PHP, and 2500 cards, was extremely slow, I though that I could try to use another language, maybe faster, thanks to Psyco module.

from psyco import full
full()

// Python
def perfectDeck(cards):
deck = range(cards)
result = range(cards)
count = 0
i = 0
while i < cards:
while count != i:
deck.append(deck[0])
deck = deck[1:]
count = count + 1
result[deck[0]] = count + 1
deck = deck[1:]
count = 0
i = i + 1
return result

Of course, in this case Psyco cannot help that much, since the most expensive operation is with the deck, and not with math.

Need for speed, C# Mousetrap


As last chance, and since the code was producing expected results, I though about fixed Arrays, without a single scriptish operation.
Instinctively, I opened my visual C# Express Edition, instead of Dev C++ to create a C version ... maybe because it's long time I am not using them, but anyway, I know that using fixed length arrays I should not have speed problems at all.

// C# with fixed lengths
static int[] perfectDeck(int cards){
int[] deck = range(cards),
result = range(cards);
for(int i = 0, count = 0; i < cards; i++){
while (count++ != i)
move(ref deck);
result[deck[0]] = count;
deck = shift(deck);
count = 0;
}
return result;
}

// C# with fixed lengths - Extra
static int[] range(int Length){
int[] result = new int[Length];
for (int i = 0; i < Length; i++)
result[i] = i;
return result;
}

static int[] shift(int[] deck){
int i = 0,
Length = deck.Length - 1;
int[] result = new int[Length];
for (; i < Length; i++)
result[i] = deck[i + 1];
return result;
}

static void move(ref int[] deck){
int last = deck[0],
i = 1,
Length = deck.Length;
while (i < Length)
deck[i - 1] = deck[i++];
deck[i - 1] = last;
}


Good enough? NO WAY, speed is more close to Python than C, so I promised myself that next version of perfectDeck function will be written in C.
At the same time, it will never be enough fast, because big input as these limits:
T = 10, 1 ≤ K ≤ 1000000, 1 ≤ n ≤ 100, 1 ≤ di ≤ K

This means that my code will perform a factorial 1000000 changes, so honestly, the next step, will be to download some code from the competition, and learn which algorithm is the most clever and simple, to perform this task, in my mind, and in my implementation, completely mechanical.

Conclusion


I like challenges, and this one was amazing. I have learned at least these things yesterday, and I hope next year, I'll be more prepared:

  • Code Jam is fantastic!

  • Do not choose the most difficult task only to be in the top 100, but read in every case all of them before you start to write a single line of code

  • Do not use mechanical procedures, but think about efficient algorithms

  • Do not focus in a code, that for more than 2 times produced wrong results, or simply it is too slow, because it means there is something wrong in the logic, or in the algorithm

  • Go back to school, because even if you are a senior programmer, you do not work for the N.A.S.A. and you do not deal, daily, with algebra, math, geometry, and related stuff



If you are still reading, thank you too, I only would like to share my Google Code Experience, and my perfect costly nightmare Mousetrap solution.

Kind Regards

Thursday, July 17, 2008

Google Code Jam, or better, how to feel a 100% idiot !

Update 2


Congratulations! The results of the Google Code Jam 2008 Qualification Round are now official, and we're happy to announce that you have advanced to Round 1

Cheers :D
-----------------------------------------

Update


Guys, I do not know what Google judges will think about him/her, but in my mind, the qualification winner, for Python language, is the user camrdale, currently in position 40 of global score grid.

That code is extremely clear (come on, that is Python, how can be different!), essential, and the logic is probably not the perfect one, but is so linear that you can understand the problem even without reading them.

Well done camrdale, and good luck for the contest :geek:
-----------------------------------------

Guys, honestly, I did not think about that kind of selection only to participate, bloody hell!

First of All, the selection started at 11pm, and since I am an employee, and an hard worker as well, I though: who care? I have 24 hours to partecipate.

This is not true at all, I have discovered only after an entire day of work, programming in front at two monitors, drinking 3 red stuff and having 2 coffee, that the classification, or the total score, is based on both results, and when you commit your result.

But who had time to read the task before? Not me, honestly!

This simply means that USA, and vampires a part, nobody could stay in the top of that list.

I was so newbye in this contest, that the instant I went in the page, after login, I started to read the task, downloading automatically the first example file. no way, bad choice as first step, so first task failed because of time, well done!

After that, I chose the second task.
I truly feel like an idiot because I still have not understand at all what the hell is the correct check to avoid trains conflicts. But I hope i will discover soon them, because I am sure somebody more fresh than me understand perfectly the task, and properly solved them.

The last one is probably the most simple one, logically speaking, but at 10:30PM and after 14 hours spent in front of my PC, I really do not know who I am, how can I remember correct geometry permutations?

One think in my mind: I am an idiot!

So thank you for the opportunity Google team, I am sure next year I will ask a week of holidays to participate in another contest like that.

Kind Regards