Desidero estendere il prototipo di oggetto String con un metodo di utilità. Ha funzionato, ma la performance è stata sorprendentemente bassa. Passare una stringa a una funzione è 10 volte più veloce rispetto a sostituire il metodo String.prototype
che sta facendo la stessa cosa. Per assicurarmi che ciò accada davvero, ho creato una semplice funzione count()
e i metodi corrispondenti.L'estensione delle prestazioni string.prototype mostra che le chiamate di funzione sono 10 volte più veloci
(stavo sperimentando, e ha creato tre diverse versioni del metodo.)
function count(str, char) {
var n = 0;
for (var i = 0; i < str.length; i++) if (str[i] == char) n++;
return n;
}
String.prototype.count = function (char) {
var n = 0;
for (var i = 0; i < this.length; i++) if (this[i] == char) n++;
return n;
}
String.prototype.count_reuse = function (char) {
return count(this, char)
}
String.prototype.count_var = function (char) {
var str = this;
var n = 0;
for (var i = 0; i < str.length; i++) if (str[i] == char) n++;
return n;
}
// Here is how I measued speed, using Node.js 6.1.0
var STR ='0110101110010110100111010011101010101111110001010110010101011101101010101010111111000';
var REP = 1e3//6;
console.time('func')
for (var i = 0; i < REP; i++) count(STR,'1')
console.timeEnd('func')
console.time('proto')
for (var i = 0; i < REP; i++) STR.count('1')
console.timeEnd('proto')
console.time('proto-reuse')
for (var i = 0; i < REP; i++) STR.count_reuse('1')
console.timeEnd('proto-reuse')
console.time('proto-var')
for (var i = 0; i < REP; i++) STR.count_var('1')
console.timeEnd('proto-var')
Risultati:
func: 705 ms
proto: 10011 ms
proto-reuse: 10366 ms
proto-var: 9703 ms
Come si può vedere la differenza è drammatica.
Il seguente dimostra che le prestazioni delle chiamate di metodo sono trascurabilmente più lente e che il codice funzione è autonomo per per i metodi.
function count_dummy(str, char) {
return 1234;
}
String.prototype.count_dummy = function (char) {
return 1234; // Just to prove that accessing the method is not the bottle-neck.
}
console.time('func-dummy')
for (var i = 0; i < REP; i++) count_dummy(STR,'1')
console.timeEnd('func-dummy')
console.time('proto-dummy')
for (var i = 0; i < REP; i++) STR.count_dummy('1')
console.timeEnd('proto-dummy')
console.time('func-dummy')
for (var i = 0; i < REP; i++) count_dummy(STR,'1')
console.timeEnd('func-dummy')
Risultati:
func-dummy: 0.165ms
proto-dummy: 0.247ms
Anche se su enormi ripetizioni (come 1e8) prototipo metodi dimostra di essere 10x volte più lento di funzioni, questo possono essere ignorati per questo caso.
Tutto questo potrebbe essere correlato solo a un oggetto String, perché semplici oggetti generici eseguono circa lo stesso quando li si passa a funzioni o chiamare i loro metodi:
var A = { count: 1234 };
function getCount(obj) { return obj.count }
A.getCount = function() { return this.count }
console.time('func')
for (var i = 0; i < 1e9; i++) getCount(A)
console.timeEnd('func')
console.time('method')
for (var i = 0; i < 1e9; i++) A.getCount()
console.timeEnd('method')
risultati:
func: 1689.942ms
method: 1674.639ms
Ho cercato su StackOverflow e binging, ma altri che il consiglio "non estendere String o Array perché inquini lo spazio dei nomi" (che non è un problema per il mio particolare progetto), non riesco a trovare nulla relativo alle prestazioni dei metodi rispetto a functio ns. Quindi dovrei semplicemente dimenticare di estendere l'oggetto String a causa di un calo delle prestazioni dei metodi aggiunti o c'è dell'altro?
Grazie per le informazioni, ma, tu sei l'ultima realizzazione è lontano da 'metodo prototype' si può sostituire con la funzione di oggetto e quindi aggiungere prototipo. quindi ottenere una nuova istanza di esso. Il risultato BTW è lo stesso. –