Today we will test 2 blocks of code that perform the following operation:
Given an array, you must select all items, degree 2 of which is greater than 5.
In the blue corner, Option A: Low-level code - old and scary (partially optimizable)
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
for ( i = 0 , res = [ ] ; i < c ; i ++ ) { t = a [ i ] ; if ( t >= 2.236067 ) { continue ; } else { res. push ( t * t ) ; } }
In the red corner Option B: High-level code - young and beautiful (not amenable to partial optimization)
- a. map ( function ( t ) { return t * t } ) . filter ( function ( t ) { return t > 5 } ) ;
Battles will take place in 3 arenas.
1. AO args - Parameters of the function activation object.
2. AO - Local variables of the function activation object.
3. Global - Global Variables.
')
In the arsenal we have the latest stable versions of all popular browsers.
All test code:
- // * * * * * * * * * * * * * * * * *
- // Activation object Arguments scope
- // * * * * * * * * * * * * * * * * *
- ( function ( a , dt , index , i , c , r , t , res ) {
- r = [ ] ;
- c = a. length ;
- dt = new Date ( ) ;
- index = 20000 ;
- while ( index - ) {
- a. map ( function ( t ) { return t * t } ) . filter ( function ( t ) { return t > 5 } ) ;
- }
- r [ 0 ] = ( new Date ( ) - dt ) ;
- dt = new Date ( ) ;
- index = 20000 ;
- while ( index - ) {
- for ( i = 0 , res = [ ] ; i < c ; i ++ ) {
- t = a [ i ] ;
- if ( t > = 2.236067 ) {
- continue ;
- } else {
- res. push ( t * t ) ;
- }
- }
- }
- r [ 1 ] = ( new Date ( ) - dt ) ;
- alert ( 'ao args:' + r ) ;
- } ( [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ) ) ;
- // * * * * * * * * * * * * * * * * *
- // Activation object scope
- // * * * * * * * * * * * * * * * * *
- ( function ( ) {
- var a = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ,
- dt ,
- index ,
- i ,
- c ,
- r ,
- t ,
- res
- ;
- r = [ ] ;
- c = a. length ;
- dt = new Date ( ) ;
- index = 20000 ;
- while ( index - ) {
- a. map ( function ( t ) { return t * t } ) . filter ( function ( t ) { return t > 5 } ) ;
- }
- r [ 0 ] = ( new Date ( ) - dt ) ;
- dt = new Date ( ) ;
- index = 20000 ;
- while ( index - ) {
- for ( i = 0 , res = [ ] ; i < c ; i ++ ) {
- t = a [ i ] ;
- if ( t > = 2.236067 ) {
- continue ;
- } else {
- res. push ( t * t ) ;
- }
- }
- }
- r [ 1 ] = ( new Date ( ) - dt ) ;
- alert ( 'ao:' + r ) ;
- } ( ) ) ;
- // * * * * * * * * * * * * * * * * *
- // Global scope
- // * * * * * * * * * * * * * * * * *
- var a = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ,
- dt ,
- index ,
- i ,
- c ,
- r ,
- t ,
- res
- ;
- r = [ ] ;
- c = a. length ;
- dt = new Date ( ) ;
- index = 20000 ;
- while ( index - ) {
- a. map ( function ( t ) { return t * t } ) . filter ( function ( t ) { return t > 5 } ) ;
- }
- r [ 0 ] = ( new Date ( ) - dt ) ;
- dt = new Date ( ) ;
- index = 20000 ;
- while ( index - ) {
- for ( i = 0 , res = [ ] ; i < c ; i ++ ) {
- t = a [ i ] ;
- if ( t > = 2.236067 ) {
- continue ;
- } else {
- res. push ( t * t ) ;
- }
- }
- }
- r [ 1 ] = ( new Date ( ) - dt ) ;
- alert ( 'global:' + r ) ;
Code:
pastebin.com/mqBdkXZGresults
FF | high level | low level |
Ao args | 458 | 92 |
AO | 474 | 122 |
Global | 479 | 162 |
Opera | high level | low level |
Ao args | 416 | 22 |
AO | 427 | 21 |
Global | 428 | 49 |
Chrome | high level | low level |
Ao args | 83 | 9 |
AO | 89 | eight |
Global | 98 | 28 |
Sa | high level | low level |
Ao args | 153 | 21 |
AO | 146 | 24 |
Global | 147 | 25 |
IE8 | high level | low level |
Ao args | dropped out | 441 |
AO | dropped out | 393 |
Global | dropped out | 822 |
Results
As you can see, there is a trend AO args | AO faster Global. This is clear from the ECMAScript specification - accessing the variables of the activation object is faster because it (JSC) is “closer to the code” than the global object.
Low-level code, many times faster than the full-level one because ECMAScript does not have blocks like in Ruby, a function is called for each element of the array, and a function call is a costly operation for JS. High level code slower up to 20 times!
Chrome is so fast because it has a JIT compilation, but for frequently used blocks of code (1 run will give the same result).
An interesting point shows Firefox: AO args (low) 92; AO (low) 122; AO args a quarter faster. Although all these variables that AO args, that AO lie in one object, but in FF AO args, judging by the results, are allocated in a separate object.
Another interesting test.
- ( function ( r , dt , index , i , j ) {
- dt = new Date ( ) ;
- index = 50000 ;
- while ( index - ) {
- // Block A
- for ( i = 0 , j = 0 ; i < 20 ; i ++ ) {
- j ++;
- }
- // -------
- }
- r [ 0 ] = new Date - dt ;
- dt = new Date ( ) ;
- index = 50000 ;
- while ( index - ) {
- // Block B
- j = 0 ;
- j ++; j ++; j ++; j ++; j ++;
- j ++; j ++; j ++; j ++; j ++;
- j ++; j ++; j ++; j ++; j ++;
- j ++; j ++; j ++; j ++; j ++;
- // -------
- }
- r [ 1 ] = new Date - dt ;
- alert ( r ) ;
- } ( [ ] ) ) ;
Which unit will be faster? Answer:
pastebin.com/hXxQb6pkUPD In the end, everything comes down to the interface redrawing (reflow, redraw), however, as my practice has shown, reflow optimization was not enough. Calls of anonymous functions ate a significant part, eliminating them received a good increase, especially in ancient browsers, which is why we suffer. Do not take this article as a guide to action, write the code as you see fit for you. I advise you to optimize as needed.