function * lazy_map ( func ) {
for ( const element of this ) {
yield func ( element )
}
}
function * lazy_filter ( func ) {
for ( const element of this ) {
if ( func ( element )){
yield element ;
}
}
}
function collect () {
const arr = [];
for ( const element of this ){
arr . push ( element );
}
return arr ;
}
function random_from () {
const index = Math . floor ( this . length * Math . random ());
return this [ index ];
}
Object . entries ({ lazy_map , lazy_filter , collect , random_from })
. forEach (([ key , value ]) => {
Array . prototype [ key ] = value ;
Object . getPrototypeOf ( function * (){}). prototype [ key ] = value ;
});
const maps = [
x => x + 1 ,
x => - 1 * x ,
x => 2 * x ,
x => x / 2 ,
x => x * x ,
x => 10 * Math . cos ( x ),
x => 10 * Math . abs ( Math . sin ( x )),
x => x / 3 ,
x => Math . floor ( x ),
x => parseInt (( x . toString (). split ( ' . ' ). slice ( 1 )[ 0 ] || '' ). substring ( 0 , 3 ), 10 ) || 0
];
const filters = [
x => x !== 0 ,
x => ( x % 2 ) === 0 ,
x => ( x % 3 ) === 0 ,
x => ( x % 3 ) === 1 ,
x => Math . abs ( x ) === x ,
x => Math . floor ( x ) === x ,
x => x <= 0 ,
x => x . toString () === x . toString (). split ( '' ). reverse (). join ( '' )
];
function random_number () {
const rand = () => Math . floor ( 100 * ( Math . random () - 0.5 ));
const numerator = rand () + rand ();
const denominator = rand () + rand ();
return denominator !== 0 ? ( numerator / denominator ) : 0
}
function random_operation () {
const min_length = 2 ;
const max_length = 7 ;
const random_length = min_length + Math . floor (( max_length - min_length + 1 ) * Math . random ());
const random_selection = Math . floor ( Math . pow ( 2 , random_length ) * Math . random ());
const signature = random_selection
. toString ( 2 )
. padStart ( random_length , ' 0 ' );
const random_pattern = signature
. split ( '' )
. map ( e => e === ' 0 '
? [ ' map ' , maps . random_from ()]
: [ ' filter ' , filters . random_from ()])
return { random_pattern , signature };
}
function perform_test ( size ) {
const { random_pattern , signature } = random_operation ();
const values = new Array ( size )
. fill ( 0 )
. map ( e => random_number ());
// Time the lazy_* functions
const lazy_start = performance . now ();
let a = values ;
for ( const [ type , func ] of random_pattern ) {
a = ( type === ' map ' )
? a . lazy_map ( func )
: a . lazy_filter ( func );
}
a = a . collect ()
const lazy_end = performance . now ();
// Time the regular functions
const regular_start = performance . now ();
let b = values ;
for ( const [ type , func ] of random_pattern ) {
b = ( type === ' map ' )
? b . map ( func )
: b . filter ( func );
}
const regular_end = performance . now ();
// Verify arrays are the same
const panic_string = ' Functions didn \' t perform the same! ' ;
if ( a . length !== b . length ) {
throw new Error ( panic_string )
}
for ( let i = 0 ; i < a . length ; a ++ ) {
if ( a [ i ] !== b [ i ]) {
throw new Error ( panic_string )
}
}
return {
lazy : lazy_end - lazy_start ,
regular : regular_end - regular_start ,
signature
}
}
const num_tests = 10000 ;
const all_test_totals = [];
for ( let i = 0 ; i < num_tests ; i ++ ) {
const size = 10000 * ( 1 + Math . floor ( 20 * Math . random ()));
const results = perform_test ( size );
results . size = size ;
all_test_totals . push ( results );
if ( i % 100 === 0 ) {
console . log ( `Completed test ${ i } ` );
}
}
console . log ();
const different_sizes = Array . from ( new Set ( all_test_totals . map ( e => e . size )))
. sort (( a , b ) => a - b );
for ( const size of different_sizes ) {
const items = all_test_totals . filter ( e => e . size === size );
const final = items
. reduce (( acc , e ) => {
acc . lazy = acc . lazy + e . lazy ;
acc . regular = acc . regular + e . regular ;
return acc ;
}, { lazy : 0 , regular : 0 });
const round = x => Math . floor ( x * 10000 ) / 10000 ;
console . log ( `Statistics for size of ${ size } (n = ${ items . length } )` );
console . log ( `Final lazy average of ${ round ( final . lazy / items . length )} ` )
console . log ( `Final regular average of ${ round ( final . regular / items . length )} ` )
console . log ( '' );
}
Statistics for size of 10000 ( n = 480 )
Final lazy average of 2.1229
Final regular average of 1.5511
Statistics for size of 20000 ( n = 550 )
Final lazy average of 4.0771
Final regular average of 3.1854
Statistics for size of 30000 ( n = 503 )
Final lazy average of 6.5147
Final regular average of 5.0976
Statistics for size of 40000 ( n = 467 )
Final lazy average of 7.6646
Final regular average of 5.8899
Statistics for size of 50000 ( n = 505 )
Final lazy average of 9.3492
Final regular average of 7.2016
Statistics for size of 60000 ( n = 461 )
Final lazy average of 13.458
Final regular average of 10.7486
Statistics for size of 70000 ( n = 526 )
Final lazy average of 15.4366
Final regular average of 12.3929
Statistics for size of 80000 ( n = 495 )
Final lazy average of 16.4056
Final regular average of 13.2401
Statistics for size of 90000 ( n = 477 )
Final lazy average of 18.2124
Final regular average of 14.5482
Statistics for size of 100000 ( n = 502 )
Final lazy average of 20.2959
Final regular average of 16.5047
Statistics for size of 110000 ( n = 471 )
Final lazy average of 22.8225
Final regular average of 17.947
Statistics for size of 120000 ( n = 520 )
Final lazy average of 25.6252
Final regular average of 20.3387
Statistics for size of 130000 ( n = 511 )
Final lazy average of 27.9891
Final regular average of 22.2645
Statistics for size of 140000 ( n = 490 )
Final lazy average of 28.1774
Final regular average of 22.1686
Statistics for size of 150000 ( n = 521 )
Final lazy average of 27.8976
Final regular average of 22.5158
Statistics for size of 160000 ( n = 486 )
Final lazy average of 35.2152
Final regular average of 28.541
Statistics for size of 170000 ( n = 489 )
Final lazy average of 36.9335
Final regular average of 29.7045
Statistics for size of 180000 ( n = 540 )
Final lazy average of 36.7676
Final regular average of 29.7667
Statistics for size of 190000 ( n = 491 )
Final lazy average of 41.1355
Final regular average of 33.8442
Statistics for size of 200000 ( n = 515 )
Final lazy average of 38.1015
Final regular average of 31.1814