मैं जावास्क्रिप्ट प्रदर्शन का शोध कर रहा हूं। मैंने सीखा है कि एक से अधिक बार पहुंचने पर, चीजों को गति देने के लिए बंद करने के चर और वर्ग के सदस्यों को स्थानीय दायरे में कॉपी करना सबसे अच्छा होता है। उदाहरण के लिए:जब ठीक-ठीक प्रदर्शन होता है, तो जावास्क्रिप्ट विधियों को कई बार कॉल करने का सबसे अच्छा तरीका क्या है?
var i = 100;
var doSomething = function() {
var localI = i;
// do something with localI a bunch of times
var obj = {
a: 100
};
var objA = obj.a;
// do something with objA a bunch of times
};
मैं इसे समझता हूं; यह नाम से मूल्य को देखने वाले दुभाषिया के लिए एक शॉर्टकट जोड़ता है। तरीकों से निपटने के दौरान यह अवधारणा बहुत अस्पष्ट हो जाती है। सबसे पहले, मैंने सोचा कि यह वही काम करेगा। उदाहरण के लिए:
var obj = {
fn: function() {
// Do something
return this.value;
},
value: 100
};
var objFn = obj.fn
objFn();
// call objFn a bunch of times
जैसा कि यह है, यह बिल्कुल काम नहीं करेगा। इस तरह की विधि तक पहुंचने से इसे अपने दायरे से हटा दिया जाता है। जब यह लाइन को पहुंचाता है। औसत, यह विंडो ऑब्जेक्ट को संदर्भित करता है और यह .value शायद अपरिभाषित होगा। ObjFn को सीधे कॉल करने और गुंजाइश खोने के बजाय, मैं obpFn.call (obj) के साथ अपने दायरे को वापस कर सकता हूं लेकिन क्या यह मूल obj.fn() के बाद कोई बेहतर या बदतर करता है?
मैंने इसका परीक्षण करने के लिए एक स्क्रिप्ट लिखने का फैसला किया और मुझे बहुत भ्रमित परिणाम मिल गए। यह स्क्रिप्ट कई परीक्षणों पर पुनरावृत्ति करता है जो उपर्युक्त फ़ंक्शन कॉल के माध्यम से कई बार कॉल करता है। प्रत्येक परीक्षण के लिए लिया गया औसत समय शरीर के लिए उत्पादन होता है।
एक वस्तु इस पर कई सरल तरीकों से बनाई गई है। यह निर्धारित करने के लिए अतिरिक्त विधियां हैं कि क्या एक विशिष्ट विधि का पता लगाने के लिए दुभाषिया को अधिक कठिन परिश्रम करना पड़ता है।
टेस्ट 1 बस यह कहता है। ए();
टेस्ट 2 एक स्थानीय चर बनाता है = this.a फिर a.call (यह) को कॉल करता है;
टेस्ट 3 स्कोप को संरक्षित करने के लिए वाईयूआई के बाइंड फ़ंक्शन का उपयोग करके स्थानीय चर बनाता है। मैंने इस पर टिप्पणी की। यूयूआई द्वारा बनाई गई अतिरिक्त फ़ंक्शन कॉल इस तरह धीमी गति से बनाते हैं।
टेस्ट 4, 5, और 6 एक के बजाय जेड का उपयोग करने के अलावा 1, 2, 3 की प्रतियां हैं।
वाईयूआई के बाद के फ़ंक्शन का उपयोग रनवे स्क्रिप्ट त्रुटियों को रोकने के लिए किया जाता है। समय वास्तविक परीक्षण विधियों में किया जाता है ताकि सेटटाइमआउट परिणामों को प्रभावित न करे। प्रत्येक समारोह को कुल 10000000 बार कहा जाता है। (यदि आप परीक्षण चलाने के लिए चाहते हैं तो आसानी से कॉन्फ़िगर करने योग्य।)
मेरा पूरा एक्सएचटीएमएल दस्तावेज़ मैं परीक्षण करने के लिए उपयोग करता हूं।
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xml:lang="en" dir="ltr">
<head>
<script type="text/javascript" src="http://yui.yahooapis.com/combo?3.1.2/build/yui/yui-min.js"></script>
<script>
YUI().use('node', function (Y) {
var o = {
value: '',
a: function() {
this.value += 'a';
},
b: function() {
this.value += 'b';
},
c: function() {
this.value += 'c';
},
d: function() {
this.value += 'd';
},
e: function() {
this.value += 'e';
},
f: function() {
this.value += 'f';
},
g: function() {
this.value += 'g';
},
h: function() {
this.value += 'h';
},
i: function() {
this.value += 'i';
},
j: function() {
this.value += 'j';
},
k: function() {
this.value += 'k';
},
l: function() {
this.value += 'l';
},
m: function() {
this.value += 'm';
},
n: function() {
this.value += 'n';
},
o: function() {
this.value += 'o';
},
p: function() {
this.value += 'p';
},
q: function() {
this.value += 'q';
},
r: function() {
this.value += 'r';
},
s: function() {
this.value += 's';
},
t: function() {
this.value += 't';
},
u: function() {
this.value += 'u';
},
v: function() {
this.value += 'v';
},
w: function() {
this.value += 'w';
},
x: function() {
this.value += 'x';
},
y: function() {
this.value += 'y';
},
z: function() {
this.value += 'z';
},
reset: function() {
this.value = '';
},
test1: function (length) {
var time = new Date().getTime();
while ((length -= 1)) {
this.a();
}
return new Date().getTime() - time;
},
test2: function (length) {
var a = this.a,
time = new Date().getTime();
while ((length -= 1)) {
a.call(this);
}
return new Date().getTime() - time;
},
test3: function (length) {
var a = Y.bind(this.a, this),
time = new Date().getTime();
while ((length -= 1)) {
a();
}
return new Date().getTime() - time;
},
test4: function (length) {
var time = new Date().getTime();
while ((length -= 1)) {
this.z();
}
return new Date().getTime() - time;
},
test5: function (length) {
var z = this.z,
time = new Date().getTime();
while ((length -= 1)) {
z.call(this);
}
return new Date().getTime() - time;
},
test6: function (length) {
var z = Y.bind(this.z, this),
time = new Date().getTime();
while ((length -= 1)) {
z();
}
return new Date().getTime() - time;
}
},
iterations = 100, iteration = iterations, length = 100000,
t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, body = Y.one('body');
body.set('innerHTML', '<span>Running ' + iterations + ' Iterations…</span>');
while ((iteration -= 1)) {
Y.later(1, null, function (iteration) {
Y.later(1, null, function() {
o.reset();
t1 += o.test1(length);
});
Y.later(1, null, function() {
o.reset();
t2 += o.test2(length);
});
/*Y.later(1, null, function() {
o.reset();
t3 += o.test3(length);
});*/
Y.later(1, null, function() {
o.reset();
t4 += o.test4(length);
});
Y.later(1, null, function() {
o.reset();
t5 += o.test5(length);
});
/*Y.later(1, null, function() {
o.reset();
t6 += o.test6(length);
});*/
if (iteration === 1) {
Y.later(10, null, function() {
t1 /= iterations;
t2 /= iterations;
//t3 /= iterations;
t4 /= iterations;
t5 /= iterations;
//t6 /= iterations;
//body.set('innerHTML', '<dl><dt>Test 1: this.a();</dt><dd>' + t1 + '</dd><dt>Test 2: a.call(this);</dt><dd>' + t2 + '</dd><dt>Test 3: a();</dt><dd>' + t3 + '</dd><dt>Test 4: this.z();</dt><dd>' + t4 + '</dd><dt>Test 5: z.call(this);</dt><dd>' + t5 + '</dd><dt>Test 6: z();</dt><dd>' + t6 + '</dd></dl>');
body.set('innerHTML', '<dl><dt>Test 1: this.a();</dt><dd>' + t1 + '</dd><dt>Test 2: a.call(this);</dt><dd>' + t2 + '</dd><dt>Test 4: this.z();</dt><dd>' + t4 + '</dd><dt>Test 5: z.call(this);</dt><dd>' + t5 + '</dd></dl>');
});
}
}, iteration);
}
});
</script>
</head>
<body>
</body>
</html>
मैंने इसे तीन अलग-अलग ब्राउज़रों में विंडोज 7 का उपयोग करके चलाया है। ये परिणाम मिलीसेकंड में हैं।
फ़ायरफ़ॉक्स 3.6.8
Test 1: this.a();
9.23
Test 2: a.call(this);
9.67
Test 4: this.z();
9.2
Test 5: z.call(this);
9.61
क्रोम 7.0.503.0
Test 1: this.a();
5.25
Test 2: a.call(this);
4.66
Test 4: this.z();
3.71
Test 5: z.call(this);
4.15
इंटरनेट एक्सप्लोरर 8
Test 1: this.a();
168.2
Test 2: a.call(this);
197.94
Test 4: this.z();
169.6
Test 5: z.call(this);
199.02
फ़ायरफ़ॉक्स और इंटरनेट एक्सप्लोरर का उत्पादन मैं कैसे उम्मीद के बारे में परिणाम है। टेस्ट 1 और टेस्ट 4 अपेक्षाकृत करीब हैं, टेस्ट 2 और टेस्ट 5 अपेक्षाकृत करीब हैं, और टेस्ट 2 और टेस्ट 5 टेस्ट 1 और टेस्ट 4 से अधिक समय लेते हैं क्योंकि प्रक्रिया के लिए एक अतिरिक्त फंक्शन कॉल है।
क्रोम मुझे बिल्कुल समझ में नहीं आता है, लेकिन यह बहुत तेज है, शायद उप-मिलीसेकंद प्रदर्शन का tweaking अनावश्यक है।
क्या किसी के पास परिणामों का अच्छा स्पष्टीकरण है? जावास्क्रिप्ट विधियों को कई बार कॉल करने का सबसे अच्छा तरीका क्या है?
आप अपने प्रश्न में इस लिंक जोड़ सकते हैं, ताकि अन्य उपयोगकर्ता परीक्षण के लिए खुद को चला सकता हूँ? - http://jsfiddle.net/Lbbx5/ – Anurag
संबंधित पढ़ा गया: ["इस" के बिना जावास्क्रिप्ट विजेट] (http://michaux.ca/articles/javascript-widgets-without-this) –
एफवाईआई, क्रोमियम (लिनक्स) का उपयोग करके मेरे (अपेक्षाकृत धीमी) प्रणाली पर, कुछ परीक्षणों के बाद ऐसा लगता है कि परिणाम फ़ायरफ़ॉक्स (केवल तेज़) के समान होते हैं: संयोजन 1/4 और 2/5 कम या कम होते हैं और 2 और 5 धीमे होते हैं 1 और 4. –