Archive for décembre 2008

Benchmark des moteurs de javascript

décembre 16, 2008

J’avais déjà signalé l’existence d’un benchmark des moteurs de JavaScript dans le projet webkit (sunspider), le coeur du navigateur Safari. Le résultat est un temps moyen pour effectuer différentes fonctions JavaScript. Naturellement, on peut suspecter que ce benchmark favorise un peu le navigateur Safari. Mais ce dernier n’est que 4ème sur 8. Il est même repassé derrière Opera. Google Chrome est incontestablement premier et Internet Explore dernier.

Navigateur (version) Test SunSpider (en ms)
Google Chrome (0.2.154.29) 2,6
Firefox (3.0.4) 4,8
Opera (9.62) 6,1
Safari (3.2.1) 6,4
K-Meleon (1.5.1) 14,5
SeaMonkey (1.1.13) 19,9
Flock (1.2.7) 23,0
Internet Explorer (7) 42.4

Un second benchmark est disponible sur le site du projet V8, le moteur de JavaScript du navigateur. Ici, le résultat est un nombre relatif. Le principe est que plus ce chiffre est grand plus le moteur est performant. Ceci a l’avantage d’être indépendant de l’ordinateur sur lequel s’effectue le test. Là Google Chrome écrase ses concurrents. Cependant, le classement n’est pas exactement le même.

Navigateur (version) Benchmark V8
Google Chrome (0.2.154.29) 1773
Opera (9.62) 170
Firefox (3.0.4) 141
Safari (3.2.1) 133
K-Meleon (1.5.1) 72
Flock (1.2.7) 69
SeaMonkey (1.1.13) 58
Internet Explorer (7) 33
Publicités

Les différentes versions du langage JavaScript

décembre 14, 2008

Cela fait plusieurs fois que je me suis posé la question s’il est correct de parler de différentes versions du langage script. Cette question m’est revenue suite à la visite du site BrowserHawk. Ce site teste les différentes capacités du navigateur web utilisé (détection du navigateur, temps de réponse). Il fournit une version langage JavaScript utilisé par le navigateur.

J’ai fais le test avec 8 navigateurs pour Windows que je considère comme « pertinents » : navigateur complet (pas une simple surcouche), mis à jour régulièrement. Ma liste est donc : Internet Explorer, Firefox, Safari, Flock, Google Chrome, K-Meleon, SeaMonkey et Opera. J’ai pris les dernières versions stables de ces navigateurs. Je suis toujours à la recherche d’autres navigateurs qui respectent les critères décrits précédemment. Voici les résultats obtenus :

Navigateur Version JS selon BrowserHawk
IE 7 1.5
Firefox 3 1.8
Safari 1.5
Flock 1.7
Google Chrome 1.8
K-Meleon 1.5
SeaMonkey 1.5
Opera 1.5

Les résultats montrent que les versions de JavaScript sont relativement récentes. Ils semblent cohérents (même résultat pour SeaMonkey et K-Meleon). Le second test est l’utilisation explicite de la version de Javascript dans une page Html comme ceci :


<script language= "JavaScript1.2">.../...</script>

ou autre manière plus standard (?)


<script type="text/javascript;version=1.2">
.../...
</script>

La seconde version de cette technique, ne fonctionne pas pour 3 navigateurs. Finalement, j’ai un gros doute sur l’interprétation de ce code. Signifie-t-il vraiment que le cette partie de script est interprétée si le navigateur supporte au moins cette version de JavaScript ? Opera ne serait-il pas un peu gros « vantard » ? Les résultats sont en fait très différents de BrowserHawk.

Navigateur BrowserHawk tag Javascript V1 tag Javascript V2
IE 7 1.5 1.3 ?
Firefox 3 1.8 1.8 1.8
Safari 1.5 1.7 ?
Flock 1.7 1.7 1.7
Google Chrome 1.8 1.7 ?
K-Meleon 1.5 1.7 1.7
SeaMonkey 1.5 1.7 1.7
Opera 1.5 2.0 1.5

Une meilleure solution serait de tester la version de JavaScript en utilisant des fonctionnalités spécifiques à chaque version. JavaScript est normalisé en tant que ECMAScript, et le site de la fondation Mozilla donne les correspondances dans le tableau qui suit. Ce qui pose la question des versions intermédiaires qui seraient spécifiées uniquement par Mozilla.

Version de Javascript Version de Firefox Version de ECMA
1.3 ECMA 262 édition2
1.5 1.0 ECMA 262 édition3
1.6 1.5
1.7 2
1.8 3.0
1.9.1 3.1
2.0 ECMA 262 édition4

Sur le site de Mozilla dit MDC « Mozilla Developer Center », on trouve plus ou moins difficilement les différences entre les versions successives JavaScript. Ce qui m’a permis d’écrire un script testant la version courante du JavaScript. Ce script permet de tester les version 1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.7, 1.8 et 1.9.1. Ce script donne avec les 8 navigateurs de références.

Navigateur BrowserHawk tag Javascript V1 tag Javascript V2 test fonctionnalités
IE 7 1.5 1.3 ? 1.5
Firefox 3 1.8 1.8 1.8 1.8
Safari 1.5 1.7 ? 1.6
Flock 1.7 1.7 1.7 1.7
Google Chrome 1.8 1.7 ? 1.6
K-Meleon 1.5 1.7 1.7 1.7
SeaMonkey 1.5 1.7 1.7 1.7
Opera 1.5 2.0 1.5 1.6

Pour valider mon script, je l’ai testé avec les différentes version de Rhino. Il s’agit d’une implémentation en Java du moteur de JavaScript de Mozilla. Attention, il n’est pas utilisé dans les navigateurs Web comme Firefox mais est un reste d’un ancien projet abandonné d’un navigateur web en Java. La version Rhino 1.5R5 correspond à la version 1.5 du JavaScript, la version 1.6R7 correspond à la version 1.6 du JavaScript, et enfin 1.7R1 à la version 1.7. Ceci fonctionne correctement avec mon script. Utiliser Rhino pour exécuter du JavaScript est en effet simple. Il suffit d’utiliser la commande qui suit (test.js est mon script de test). Il existe une méthode main dans ce jar.


java -jar js.jar -f test.js

Au final, on voit qu’il existe un flou dans les différentes version du langage JavaScript mais qu’une version 1.3 ou 1.5 semble un compromis acceptable pour l’instant. Notons bien ici que je parle du coeur du langage et non de l’implémentation du DOM, l’accès aux éléments d’une page Web.

Voici le fichier test.js

function testVersion() {
var myArray = ['a', 'b', 'a', 'b', 'a'];
var res="";
var myNumber=2489.8237
var myString="eer";

//version 1.0
var version1_0=0;
if(Date.parse)
version1_0= version1_0+1;

res=res+"version 1.0 : "+version1_0+"/1 \n";

//version 1.1
var version1_1=0;
if(myArray.join)
version1_1= version1_1+1;

if(myArray.toString)
version1_1= version1_1+1;

if(myArray.reverse)
version1_1= version1_1+1;

if(myArray.sort)
version1_1= version1_1+1;

res=res+"version 1.1 : "+version1_1+"/4 \n";

//version 1.2
var version1_2=0;
if(myArray.concat)
version1_2= version1_2+1;

if(myArray.slice)
version1_2= version1_2+1;

if(myArray.pop)
version1_2= version1_2+1;

if(myArray.push)
version1_2= version1_2+1;

if(myArray.shift)
version1_2= version1_2+1;

if(myArray.splice)
version1_2= version1_2+1;

if(myArray.unshift)
version1_2= version1_2+1;

res=res+"version 1.2 : "+version1_2+"/7 \n";

//version 1.3
var version1_3=0;
if(myArray.push) {
var myArray2 = ['a', 'b', 'a', 'b', 'a'];
//V1.3 push retourne la taille du tableau.
i=myArray2.push('e','r');
if(i==7)
version1_3= version1_3+1;
}

if(myArray.splice) {
var myArray2 = ['a', 'b', 'a', 'b', 'a'];
myArray3=myArray2.splice(1,3,'z');
if(myArray3.length==3);
version1_3= version1_3+1;
}

//Boolean(new Boolean(false)) return false = 1.2 or -
//return true 1.3 or +
if(Boolean(new Boolean(false)))
version1_3= version1_3+1;

res=res+"version 1.3 : "+version1_3+"/3 \n";

//version 1.5
var version1_5=0;
if(myNumber.toFixed)
version1_5= version1_5+1;

if(myNumber.toExponential)
version1_5= version1_5+1;

if(myNumber.toPrecision)
version1_5= version1_5+1;

res=res+"version 1.5 : "+version1_5+"/3 \n";

//version 1.6
var version1_6=0;
if(myArray.indexOf)
version1_6= version1_6+1;

if(myArray.lastIndexOf)
version1_6= version1_6+1;

if(myArray.filter)
version1_6= version1_6+1;

if(myArray.forEach)
version1_6= version1_6+1;

if(myArray.every)
version1_6= version1_6+1;

if(myArray.map)
version1_6= version1_6+1;

if(myArray.some)
version1_6= version1_6+1;

res=res+"version 1.6 : "+version1_6+"/7 \n";

//version 1.7
var version1_7=0;
if(this.Iterator)
version1_7= version1_7+1;

res=res+"version 1.7 : "+version1_7+"/1 \n";

//version 1.8
var version1_8=0;
if(myArray.reduce)
version1_8= version1_8+1;

if(myArray.reduceRight)
version1_8= version1_8+1;

res=res+"version 1.8 : "+version1_8+"/2 \n";

//version 1.9.1
var version1_9_1=0;
if(myString.trim)
version1_9_1= version1_9_1+1;

if(myString.trimLeft)
version1_9_1= version1_9_1+1;

if(myString.trimRight)
version1_9_1= version1_9_1+1;

if(Object.getPrototypeOf)
version1_9_1= version1_9_1+1;

res=res+"version 1.9.1 : "+version1_9_1+"/4 \n";

print(res);

if(version1_9_1==4)
return "1.9.1";
else if(version1_8==2)
return "1.8";
else if(version1_7==1)
return "1.7";
else if(version1_6==7)
return "1.6";
else if(version1_5==3)
return "1.5";
else if(version1_3==3)
return "1.3";
else if(version1_2==7)
return "1.2";
else if(version1_1==4)
return "1.1";
else if(version1_0==1)
return "1.0";
else
return "inconnue";

}
testVersion();