Avoid reading outside of collection bounds

Consider the following collection:

    const array = ['a', 'b', 'c'];

Retrieving `array[0]` can be done relatively quickly. However, when the property doesn’t exist on the receiver, JavaScript engines must continue to look up the prototype chain until either the property is found or the chain ends. This is inherently slower than *not* doing any prototype chain lookups. Retrieving an out-of-bounds index, e.g. `array[3]`, triggers this scenario, resulting in decreased performance.

This patch changes the way some loops are written to avoid running into the slow case unnecessarily.

A more in-depth explanation featuring a jQuery-specific example can be found here: https://ripsawridge.github.io/articles/blink-mysterium/
This commit is contained in:
Mathias Bynens 2017-08-29 09:56:03 +02:00
parent 692f9d4db3
commit 9d8431c832
2 changed files with 6 additions and 2 deletions

View File

@ -285,9 +285,11 @@ jQuery.extend( {
cleanData: function( elems ) { cleanData: function( elems ) {
var data, elem, type, var data, elem, type,
special = jQuery.event.special, special = jQuery.event.special,
length = elems.length,
i = 0; i = 0;
for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { for ( ; i < length; i++ ) {
elem = elems[ i ];
if ( acceptData( elem ) ) { if ( acceptData( elem ) ) {
if ( ( data = elem[ dataPriv.expando ] ) ) { if ( ( data = elem[ dataPriv.expando ] ) ) {
if ( data.events ) { if ( data.events ) {

View File

@ -66,7 +66,9 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
fragment.textContent = ""; fragment.textContent = "";
i = 0; i = 0;
while ( ( elem = nodes[ i++ ] ) ) { l = nodes.length;
for ( ; i < l; i++ ) {
elem = nodes[ i ];
// Skip elements already in the context collection (trac-4087) // Skip elements already in the context collection (trac-4087)
if ( selection && jQuery.inArray( elem, selection ) > -1 ) { if ( selection && jQuery.inArray( elem, selection ) > -1 ) {