Wherefore Art Thou Challenge

Hey everyone,

I just submitted the code for Wherefore Art Thou challenge and, after a lot of thinking, I came up with two solutions to this problem and I want to share some thoughts with you guys.

WARNING: IF YOU DIDN’T PASS THE CHALLENGE JUST YET, LEAVE THIS POST :slight_smile:

Ok. So the first solution I found was the least “elegant” code, but more intuitive to me. I used a filter() function, a for…in loop and some ternary operators in 10 lines of code. Here you have it:

function whatIsInAName ( collection , source ) {
  return collection.filter( obj => {
    let match = false;
    for ( const sourceKey in source )
      match =  obj.hasOwnProperty( sourceKey )
            && source[sourceKey] == obj[sourceKey]
            ?  true : false;
    return match ? obj : null;
  } );
}

Then I wanted to do it another way, to reduce the number of lines, to try more “functional programming” (map, reduce, etc), and to see it from another perspective. I used filter(), map() and reduce() functions in 7 lines after some time reading examples:

function whatIsInAName ( collection , source ) {
  return collection.filter( obj => {
    return Object.keys( source )
      .map( key => obj.hasOwnProperty( key ) && source[ key ] === obj[ key ] )
      .reduce( ( accum , currItem ) => accum && currItem );
  } );
}

So far so good. BUT, I wanted to know how good they both performed in terms of speed, I found out that the first solution executes faster (actually way faster, more than half the time):

1st solution: 0.5 milliseconds.
2nd solution: 0.19999999999998863 milliseconds.

What do you think about this? Maybe I didn’t do enough tests? I’d like to know your opinion on the matter because, at least in this case, I find easier to read my first solution and it turns out to be also faster.

Happy coding!

Eh? 0.2 is less than 0.5. Anyway, mostly these benchmarks are pretty irrelevant but if you really want to compare then compare an imperative with a functional approach (just loops, not higher order functions), there’s barely any difference between these two

1 Like

Sorry, I didn’t know about that tag :slight_smile:

I did the tests with this and I placed the wrong numbers (0.5 was the second solution hehe. I tested it with the provided examples by the challenge only, but most of them outputs similar results.

I just found the results interesting. Only ten lines of code, but maybe a huge number of lines can make a difference.

Number of lines won’t make much difference, it’s how the code executes that makes the difference. A for loop solution is [probably] always going to be faster, as is [probably] not creating anything on the fly. “Probably” because it’ll depend on how the specific JS engine works - older engines will only have an interpreter, but newer engines compile the code, and are pretty good at automatically inlining things. 0.5ms and 0.2ms is a tiny, tiny difference; the first takes twice long as the second on one particular engine under one particular set of system specs, but the numbers are so small that it’s difficult to read anything meaningful from one test.

Edit: be very careful about optimizing JS unless you really need to (eg you are writing a virtual DOM implementation, or you have some game logic that is performance critical); there is lots of advice and afaics most of it is wrong due to constant improvements in JS engine technology. V8 (the engine that powers Chrome and Node), for example, does not have an interpreter. Instead, it has two compilers: the first takes your JS code and converts it to unoptimized machine code. If there is something that prevents optimization, it stays as that. But if not, the second compiler, which optimizes the machine code for speed, can be run. Examples of stuff that prevents optimization: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers

2 Likes