jquery, plugins
Benchmark 1.0
21 May 2008 | CommentsPerchè questo plugin?
Secondo molti se io salvo un dato in un elemento DOM all’interno di una proprietà “expando” in fase di lettura sarò più veloce rispetto ad avere lo stesso dato in un attributo html.
Il plugin sembra confermare questa tesi.
Intanto cosa indica il grafico. Se spiego il grafico sarà più semplice capire come usare il plugin e testarlo per i vostri scopi.
Il grafico indica che all’aumentare degli elementi html su una pagina (in questo caso da uno a trenta immagini) effettivamente leggere un valore da un attributo html o leggere un valore dalla proprietà di un oggetto (lo stesso oggetto d’altra parte) sono due operazioni diverse e effettivamente una è più veloce dell’altra. E ci mancherebbe! La prima è un funzione di lettura/scrittura (oltretutto jQuery over DOM). La seconda è una lettura/scrittura nativa di una proprietà di un oggetto.
Le funzioni:
var mywrite = function(ref, serie){
if(serie == 1)
ref.original = jQuery(ref).attr("src");
else
jQuery(ref).attr("original", jQuery(ref).attr("src"));
}
var myread = function(ref, serie){
if(serie == 1){
var read = ref.original;
read = null;
}else{
var read = jQuery(ref).attr("original");
}
}
il parametro serie indica quale test sto eseguendo. In questo caso io voglio un confronto tra “due alternative”. Avessi scritto delle funzioni più complesse potevo avere più test, e quindi più serie.
(Probabilmente cercando di influire il meno possibile sul test. La strada dell’if magari è da rivedere).
Test 0:
Scrittura:
jQuery(ref).attr(“original”, jQuery(ref).attr(“src”));
Lettura:
var read = jQuery(ref).attr(“original”);
Test 1:
Scrittura:
ref.original = jQuery(ref).attr(“src”);
Lettura:
var read = ref.original;
Ma come faccio a far eseguire queste funzioni?
Queste funzioni vengono passate al benchmark: vediamo come.
Innanzitutto questi benchmark sono “orientati al DOM” nel senso che io voglio testare la velocità di una certa azione su una pagina web.
Quindi mi serve una sorta di template html da creare per poi applicare la funzione.
var html = jQuery('<img alt="new Mikado logo 600 3D" src="http://maxb.net/repository/images/14.jpg" />');
A questo punto setto il benchmark:
Benchmark.settings({
maxc : 30,
args : [0,1] ,
mod : 10,
prepare : html
});
Questi settaggi mi dicono che
- io ho due serie di test (args).
- Che voglio testare su una pagina web formata da 30 elementi (maxc).
- In realtà i test verranno eseguiti con un elemento in più alla volta fino ad arrivare ad avere 30 elementi. Il parametro mod mi permette di saltare ogni N elementi. In questo caso verranno eseguiti 3 test uno con 10, uno con 20, uno con 30 elementi (mod)
- Che l’html da creare prima del test è contenuto nella variabile html (prepare)
Ecco il codice per il benchmark
Benchmark.each(function(nr, serie){
jQuery(selector).benchmark({
test : [ func1, func2 ] //....
}, nr, serie);
});
La parte da personalizzare è l’array con i nomi di funzioni (o con funzioni anonime).
E il selettore.
Nel mio test ho dato da creare delle immagini. Il selettore sarà “img”.
Benchmark.each(function(nr, serie){
jQuery('img').benchmark({
test : [ mywrite , myread ]
}, nr, serie);
});
Alla fine dei test verrà visualizzato tramite GOOGLE API CHARTS un grafico per capire al volo i risultati.
Vedere gli altri esempi :
- ATTR VS EXPANDO
- ATTR VS EXPANDO (funzioni anonime passate al benchmark)
- YCODASLIDER no pack
- YCODASLIDER pack version
- Chili 2.0 plugin (Velocissimo!)
- YCodaSlider Benchmark Explanation – NOT VALID FOR RESULTS
- CodaSlider Benchmark Explanation – NOT VALID FOR RESULTS
- CodaSlider Benchmark
- YCodaSlider Benchmark
- YCodaSlider Benchmark – Stress – 50 slider
- CodaSlider Benchmark – Stress – 50 slider
Il test mi dice che il pack dei javascript non influisce sulla velocità.
Devo provare con le librerie jQuery UI.
Un confronto tra coda-slider 1.1.1 di Niall Doherty e il mio YCodaSlider.
Tutti questi dati non hanno alcuna valenza. Spero che mi permettano di capire dove è possibile migliorare le prestazioni e evitare memory leak. (Tra l’altro il mio plugin su poche istanze è più lento.)
| YCodaSlider 2.0 | Coda-Slider 1.1.1 | |
|---|---|---|
| 5 | 459ms | 337ms |
| 10 | 908ms | 759ms |
| 20 | 2069ms | 2316ms |
| 30 | 3497ms | 4124ms |
| 40 | 4327ms | 6278ms |
| 50 | 5386ms | 9067ms |
$Date: 2008-05-21 20:48:10 +0200 (mer, 21 mag 2008) $
$Rev: 106 $corretto 2 bachi:
- il clone non può avere la stessa classe del target. Se si bisogna invocare il benchmark con un prefisso sul selettore target : Benchmark.prefix() + “.target”
- se il selettore seleziona più elementi di quanti il benchmark se ne aspettasse il benchmark non viene eseguitoTODO:
l’oggetto da clonare (options.prepare) deve poter essere un array in modo che ogni serie possa avere il suo clone da appendere.
/*
*
* Benchmark plugin 1.0
* $Date: 2008-05-21 20:48:10 +0200 (mer, 21 mag 2008) $
* $Rev: 106 $
* @requires jQuery v1.2.3
*
* Copyright (c) 2008 Massimiliano Balestrieri
* Examples and docs at: http://maxb.net/blog/
* Licensed GPL licenses:
* http://www.gnu.org/licenses/gpl.html
*
*/
//http://www.dustindiaz.com/basement/sugar-arrays.html
Array.prototype.indexOf = function(el, start) {
var start = start || 0;
for ( var i=0; i < this.length; ++i ) {
if ( this[i] === el ) {
return i;
}
}
return -1;
};
if(!window.Benchmark)
Benchmark = {};
Benchmark = {
show : false,
start : false,
finish : false,
elapsed : false,
flag : false,
impossible : false,
url : 'http://chart.apis.google.com/chart?',
maxv : 0,
maxc : 0,
data : [],
labels : [],
api : {},
options : {},
settings : function(options){
Benchmark.options = jQuery.extend({
maxc : 1 ,//maxc : è il limite al ciclo
args : false ,//serie del grafico, ciclo esterno. passa parametro
mod : 1, //il benchmark salta ogni?
prepare : false,
clean : true
}, options);
Benchmark.maxc = Benchmark.options.maxc;
if(Benchmark.options.args === false)
Benchmark.impossible = true;
},
chartapi : function(options){
//http://chart.apis.google.com/chart
Benchmark.api = jQuery.extend({
dimensions : "1000x300",
chxt : "x,y",
chds : "0,",
chxr1 : "0,0,",
chxr2 : "1,0,",
cht : "lc",
labels : "",
chco : "ff0000,00ff00"
}, options);
Benchmark.make_url();
},
chart : function(options){
if(Benchmark.flag === false)
Benchmark.chartapi(options);
var dim = Benchmark.api.dimensions.split("x");
jQuery("body").append("<p>"+Benchmark.url+"</p>");
jQuery("body").append('<img width="'+dim[0]+'" height="'+dim[1]+'" src="'+Benchmark.url+'" />');
},
make_url: function(){
Benchmark.url += 'chs=' + Benchmark.api.dimensions + '&';
Benchmark.url += 'chxt=' + Benchmark.api.chxt + '&';
Benchmark.url += 'chds=' + Benchmark.api.chds + Benchmark.maxv + '&';
Benchmark.url += 'chxr=' + Benchmark.api.chxr1 + Benchmark.maxc + '|' + Benchmark.api.chxr2 + Benchmark.maxv + '&';
Benchmark.url += 'chl=0|' + Benchmark.labels.join("|") + '&';
var data = '';
for(serie in Benchmark.data)
data += "0," + Benchmark.data[serie].join(",") + "|";
data = data.substr(0, data.lastIndexOf("|"));
Benchmark.url += 'chd=t:' + data + '&';
Benchmark.url += 'cht=' + Benchmark.api.cht + '&';
Benchmark.url += 'chdl=' + Benchmark.api.labels.join("|") + '&';
Benchmark.url += 'chco=' + Benchmark.api.chco ;
},
prepare : function(p){
jQuery('<div id="benchmark-dom'+p+'">').hide().appendTo("body");
if(Benchmark.show)
jQuery('#benchmark-dom'+p).show();
},
serie : function(p, arg){
jQuery('#benchmark-dom'+p).append('<div id="serie-'+p + '-' + arg +' />');
},
append : function(p, arg){
for(var x = 1;x <= p; x++){
var a = Benchmark.options.prepare.attr("id", "test-" + p + '-' + arg + '-' + x).clone();
jQuery(a).appendTo('#serie-'+p+'-'+arg);
}
},
clean : function(p, serie){
jQuery('#serie-' + p + '-'+ serie).empty();
},
stop : function(benchmarkid, serie){
Benchmark.finish = new Date().getTime();
//console.log("FINITO");
Benchmark.elapsed = Benchmark.finish - Benchmark.start;
if(Benchmark.elapsed > Benchmark.maxv)
Benchmark.maxv = Benchmark.elapsed;
//labels
if(Benchmark.labels.indexOf(benchmarkid) == -1)
Benchmark.labels.push(benchmarkid);
//data
if(!Benchmark.data[serie])
Benchmark.data[serie] = [];
Benchmark.data[serie].push(Benchmark.elapsed);
Benchmark.start = Benchmark.elapsed = Benchmark.finish = false;
if(Benchmark.options.clean)
Benchmark.clean(benchmarkid, serie);
},
each : function(test){//test){
if(Benchmark.impossibile)
return;
//console.log("inizio i benchmark");
for(var p = 1;p <= Benchmark.maxc; p++){
if(p % Benchmark.options.mod === 0){
//console.log("benchmark " + p);
if(Benchmark.options.prepare)
Benchmark.prepare(p);
//lavora sulle serie
for(arg in Benchmark.options.args) {
Benchmark.serie(p, arg);
//console.log("inizio la serie " + arg + " di " + Benchmark.options.args[Benchmark.options.args.length -1]);
Benchmark.append(p, arg);
//console.log("appendo i figli " + p);
//esegue init()
test(p, arg);
}
}
}
},
prefix : function(nr, serie){
return '#benchmark-dom' + nr +' > #serie-'+ nr +'-'+ serie + '> ';
},
init : function(options, nr, serie){
options = jQuery.extend({
test : function(){}
}, options);
var container = jQuery(this);
var size = container.size();
if(nr != size)
alert("Error. remove class from clone");
Benchmark.start = new Date().getTime();
return jQuery(this, container).each(
function(z){
var that = this;
for(func in options.test){
options.test[func](that, serie);//eseguita la funzione utente
}
if(z == (size -1))
Benchmark.stop(nr, serie);//nr è più sicuro
}
);
}
};
jQuery.fn.benchmark = Benchmark.init;
This entry was posted in jquery, plugins and tagged benchmark, javascript, jquery, plugins. Bookmark the permalink.
← Once Upon a Time (ehm… nowadays) in Italy Benchmark 1.0 – Peso dei metodi → 