Git Product home page Git Product logo

performance-analysis-js's Introduction

Performance-Analysis

Comparing native JavaScript array methods map, reduce, filter, and find against for loop, forEach loop and lodash methods. The analysis uses basic operations and heavy data manipulation to analyze the execution speed of each method.

To run

  1. Run npm install
  2. Generate the data for the tests by running npm run seed.
    • The default array is 10000 elements in length. You can create an array of a custom length by passing the desired size as an arugment, like so npm run seed 100000.
  3. For a small data set performance report run npm run t:s.
    • This runs the analysis on the first 5 elements of the array.
  4. For a performance report on the whole array run npm run t:l

To test your own function create them in the formulas.js file.

Results for small data set of array size 5 - 1000

small_data_set_result

Results for mid data set of array size 3000 - 20000

mid_data_set_result

Results for large data set of array size 50000 - 1000000

large_data_set_result

Coming Soon

  1. Ramda.js test
  2. Caching (inline, warm) considerations
  3. GC considerations

Note

  1. These results are computed using Node V8 v5.8.283.41
  2. These result does not consider the JIT, inline caching, hidden classes, deoptimizations, garbage collection, pretenuring etc.
  3. Result may vary as per env's.
  4. Red colour highlight in the above images is just for reference, will soon change.

Discussion/Posts

  1. https://news.ycombinator.com/item?id=17050798
  2. https://medium.com/@ideepak.jsd/javascript-performance-test-for-vs-for-each-vs-map-reduce-filter-find-32c1113f19d7

performance-analysis-js's People

Contributors

dg92 avatar stmcallister avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

performance-analysis-js's Issues

Why the double + signs?

This is more of a question than an issue. I'm noticing that there are + signs than I'm used to, and I'm wondering what the purpose is. For example, on the reduce section, the equation looks like

(+posts[i].upvotes + +posts[i].downvotes + +posts[i].commentCount)

with + symbols before each element and then additional ones in between. I've tested with

(posts[i].upvotes + posts[i].downvotes + posts[i].commentCount)

and it seems to work. Is there something that the additional symbols are doing?

Tests are done without checking the results.

The results are practically invalid since the tests don't actually care about the results. This means that javascript engines can and will optimise away critical code.

*************** Map performance check ***************
js map: 15.636ms
for loop: 8.461ms
for each: 17.376ms
lodash map: 18.545ms
*************** Map performance check with result check ***************
js map: 6.106ms
sum: 49886314
for loop: 22.985ms
sum: 49886314
for each: 7.250ms
sum: 49886314
lodash map: 27.305ms
sum: 49886314

The latter case is where I just console.log the sum of commentCounts after each run and outside the timing blocks. This completely turns the results around.

This tests are not valid.

You are not taking in consideration time needed to work with memory, but you have to in such tests, where main work depends exactly on construction of big arrays and freeing them before next test.

Simple example.
In mapPerformance(posts) execution time of "forEach" depends on running order,
just move "forEach" block before "for loop", and you will see it starts to run "faster" than "for loop".

I have changed order and added 2 copies of tests, several runs:
posts.length: 100000

*************** Map performance check ***************
js map: 76.214ms
forEach1: 18.749ms
for loop1: 41.964ms
for loop2: 25.268ms
forEach2: 44.676ms
lodash map: 39.380ms
*************** Map performance check ***************
js map: 54.923ms
forEach1: 22.339ms
for loop1: 40.497ms
for loop2: 25.301ms
forEach2: 36.331ms
lodash map: 46.882ms
*************** Map performance check ***************
js map: 52.755ms
forEach1: 13.488ms
for loop1: 36.412ms
for loop2: 18.201ms
forEach2: 32.484ms
lodash map: 29.668ms
*************** Map performance check ***************
js map: 58.978ms
forEach1: 18.157ms
for loop1: 42.817ms
for loop2: 25.558ms
forEach2: 40.048ms
lodash map: 37.493ms

What we see? What conclusion?
What can we say with confidence?
Just that forEach and for loop have no difference and you can choose what you want.

PS:
node v10.16.1

for loop optimisation

You could optimize the for loop by hoisting your iterator and posts.length. It would take much less time if you didn't have to check posts.length every time.

for(let i=0; i<posts.length; i++) {
        posts[i].upvotes = (posts[i].upvotes +posts[i].commentCount)/divider;
}

Would take less time implemented this way:

var i;
const len = posts.length;

for(i=0; i<len; ++i) {
        avg += (posts[i].upvotes +posts[i].downvotes +posts[i].commentCount)/3;
}

Find should break when obj is found

The for loop - find test is significantly slower because it should break when the object is found, since it wants the first occurrence in the array

for of loop?

Can the for-of loop end result be added to this comparison table in the readme?

Test Improvement Ideas

Just a couple thoughts to improve the tests if you're still working on this.

  1. commit the seed data. Probably doesn't make a huge difference, but it would ensure that every run of the test was using the exact same randomly generating data. (On a similar thought, I wonder what would happen if all your test data was zeroes)
  2. It would be a little more interesting if you ran each method on each data set size multiple times
  3. If you ran every single test run in a brand new Docker container, it would probably get you a little more consistency. It would take a lot more effort and may not be worth, but it would be interesting.

I might pitch in and try my hand at one or all of these. Regardless of the results, it's an interesting idea you had to think to test these things.

invalid numbers

These perf numbers are invalid as you're NOT measuring the same thing - for example, according to the docs:

The map() method creates a new array with the results of calling a provided function on every element in the calling array.

The for loop code doesn't do the same thing as map would:

    console.time('for loop');
    for(let i=0; i<posts.length; i++) {
        posts[i].upvotes = (+posts[i].upvotes + +posts[i].commentCount)/divider;
    }
    console.timeEnd('for loop');

Sure, you can say that you're using all these functions just to iterate over an array, but that would clearly be a misuse of the APIs

find() has other issues - your for loop implementation returns the last element as supposed to the first one from Array.find.

When doing perf analysis it is really important for the code alternative to do the same thing, otherwise the comparison is pointless

Not an issue, just a question.

Hey const {
map,
reduce,
filter,
find,
random
} = require('lodash');

Is this syntax pulling specific methods from a library ?? ( map, reduce, filter, find and random) are pulled from lodash here right ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.