Monthly Archives: June 2019

A performance test of the JavaScript Array.some function in Node.js

In my previous blog post, I talked about using the Array.some method as a handy tool for looping over “some” array elements until a condition is satisfied. Well, once in a while, you’re going to come across an article which is critical of “new-fangled” Array methods. It’s a known issue that some of these array methods perform poorly in comparison to the “old-fashioned” for loop.

It’s not that people don’t like the new methods. In the article mentioned above, Yotam Kadishay says they make JavaScript “more functional”, and writing code is “more fun and smooth” with the addition of these new methods. But if your code runs like a dog, no one is going to really care about how much fun you had writing it, will they?

Mr. Kadishay wrote a good article, and you should read it! He performance tested some of the newer Array methods, and found they tend to run slower than the older, tried and true ones. But he didn’t discuss the performance of the Array.some method. Array.some is actually not so new-fangled – it has been around since JavaScript 1.6 (2006).

So I’m going to performance test the implementation of Array.some, which is what I used in implementing my startsWithVowel method I wrote in my previous post. For test purposes, I’ve snagged Peter Norvig’s list of 100,000 words – they are all uppercase. I saved this list to my /tmp directory.

To be fair, I might want to run my performance test with a list of lowercased words, a mix of cases and so on. But for now let’s just work with this list.

I’m going to test this in Node.js. I use nvm (Node Version Manager) to use whichever version of node I’m interested in testing. I’ll test using node 8.16. I have node installed on a development environment running Ubuntu 16.04. To run my test, I fire up a node command line as follows:

nvm use 8.16
node
>

Then I just copy and paste the code below into the command line and look at the results:

/* Displays results */
var finishAndPrint = function(words) {
    console.log("words length: " + words.length);
    console.log("First word: " + words[0]);
    console.log("Last word: " + words[words.length-1]);
};

/* This test function is guaranteed to never match a word in the Norvig list of words */
var testFunction = function(item) {
    return item === "gsdjkoeu";
};

/* A performance test using the Array.some method: */
var performanceTestSome = function(words) {
    const {performance} = require('perf_hooks');
    let t0 = performance.now();
    let result = words.some(function(el, i) {
        return testFunction(el);
    });
    let t1 = performance.now();
    console.log("The some method took " + (t1 - t0) + " milliseconds and the result was " + result + ".");
};

/* A performance test using a simple for loop: */
var performanceTestForLoop = function(words) {
    const {performance} = require('perf_hooks');
    let len = words.length;
    var result = false;
    let t0 = performance.now();
    for (var i = 0; i < len; i++) {
        if (testFunction(words[i])) {
            // This code is necessary so the function does the same thing as the "some" method
            result = true;
            break;
        }
    }
    let t1 = performance.now();
    console.log("The for loop method took " + (t1 - t0) + " milliseconds and the result was " + result + ".");
};

/* Read the words: */
fs.readFile('/tmp/count_1w100k.txt', {encoding: 'utf-8'}, function(err, data) {
    var words = [];
    var lines = data.split('\n');
    lines.forEach(function(row, i) {
        var items = row.split('\t');
        if (items[0].length > 0) {
            words.push(items[0]);
        }
    });
    finishAndPrint(words);
    performanceTestSome(words);
    performanceTestForLoop(words);
    performanceTestForLoop(words);
    performanceTestSome(words);
});

Here’s the output:

> words length: 100000
> First word: THE
> Last word: PGY
> The some method took 2.5111299753189087 milliseconds and the result was false.
> The for loop method took 1.983236014842987 milliseconds and the result was false.
> The for loop method took 0.6664620041847229 milliseconds and the result was false.
> The some method took 1.9726130068302155 milliseconds and the result was false.

Huh, there’s some kind of optimization going on in that for loop. I didn’t investigate. I’m assuming the first run is more accurate. It looks like the for loop is slightly more performant than the some method.

I repeated the test in a couple of different ways, because I wanted to make sure that the order of calling didn’t matter. In each case, I exited the node command line using .exit and restarted it. Here’s another example output, in which I called the for loop method twice followed by the some test. In this case, it looks as if the performance difference is negligible on the first run of each method. However, it continues to appear that there’s some optimization which is done when the for loop method is used the second time, but not when some is used.

> words length: 100000
> First word: THE
> Last word: PGY
> The for loop method took 2.146267980337143 milliseconds and the result was false.
> The for loop method took 0.590969979763031 milliseconds and the result was false.
> The some method took 2.074671983718872 milliseconds and the result was false.
> The some method took 1.9943189918994904 milliseconds and the result was false.

Since I’ve got my code here and explained the methods I used, together with the environment, you can repeat the tests for yourself. I think it’s important to give as much information about your methods and environment when running performance tests. And if I were going to get more serious, I’d probably do some statistics, maybe run this test multiple times, and do a chi-squared test or some sort of test to make sure that my results are not a fluke.

Before you consider performance testing, think about whether performance will ever truly be an issue. Is it worth performance testing when you’re building a prototype for a startup and the code may never even get used by more than a few people? Is it worth sacrificing readability and maintainability in order to run the most performant code? Robert Harvey wrote this comment in response to a Stack Overflow question about performance testing Node.js:

you can have slow code run forever where a user won’t notice it, and pretty fast code running where they do, and they will complain about the pretty fast code not being fast enough. Or that your request to your server API took 220ms. Or something else like that. The point remains that if you take a profiler out and go looking for work to do, you will find it, but it may not be the work your users need.

It is probably true that performance is more important when writing server-side code. Your server’s going to be fielding a bunch of requests from multiple users; whereas the browser client is just dealing with “one user” at a time. Of course, you want good performance on the client side as well. You may want to play it safe and use for loops everywhere. That may be overkill 🙂 You’d still better know how Array methods work, and know how to read them, because there are plenty of developers and companies which are not nearly that strict about it.

In my next blog post, I’ll run the same test using JavaScript on the client.

How to check if a word starts with a value stored inside an array in JavaScript

Suppose you have an array of letters, and a word, and you need a little JavaScript code which answers the question: “Does this word start with any of the letters in my array?”. As an example, suppose the word is “aardvark” and your array is an array of vowels: [“a”, “e”, “i”, “o”, “u”]. At a glance, you can say that “aardvark” does start with the vowel “a”, so the answer to the question is yes.

Now you need to write the JavaScript code which will do the work for you, for any word at all.

First, you can use the fact that the JavaScript String type has a method startsWith which returns true if the string starts with the input value.

For example:

let value = "aardvark".startsWith("a");
console.log(value); // prints "true"

That’s a good start. Now we need to check all the vowels in our array. There’s a very handy Array method, some, which can be used for this purpose. Let’s look at how it works for this example:

let vowels = ["a", "e", "i", "o", "u"];
let value1 = vowels.some(function(vowel) {
    return "aardvark".startsWith(vowel);
});

The way this code works is that some evaluates the passed in callback function for every vowel in the array until it finds one which returns true (or more correctly, a “truthy” value). Then, it stops, and doesn’t look at any more vowels in the array – the output of the method is true. If the function never returns true – for example, if we replaced “aardvark” with “camel” – then the output of some would be false.

Let’s rework this code so that it can be easily reused for any word:

let startsWithVowel = function(word) {
    return vowels.some(function(vowel) {
        return word.startsWith(vowel);
    });
};

Then you can test this for any word you want. For example, open Chrome browser, open the JavaScript console by typing Ctrl+Shift+J, and type in the above code to define your function. Then you can test the function manually with different inputs, like this:

> startsWithVowel("aardvark");
true
> startsWithVowel("umbrella");
true
> startsWithVowel("camel");
false

The cool part about the implementation of startsWithVowel is that it won’t perform word.startsWith(vowel) on every single element in the array if it doesn’t need to do so. It only evaluates this until it finds an element which causes word.startsWith(vowel) to return true. In the case of “aardvark”, that’s the very first element.

You may be wondering “why do I have to use this Array.some method? I could have used a for loop.” Yup, you’re right. Here’s a different implementation which uses a for loop to do the same thing:

let startsWithVowelLoop = function(word) {
    let l = vowels.length;
    let result = false;
    for (let i = 0; i < l; i++) {
        if (word.startsWith(vowels[i])) {
            result = true;
            break;
        }
    }
    return result;
};

When I was first introduced to the some method, I had the same doubts. Why use this method to do something that I already knew how to do perfectly well with a loop? There are a couple of reasons. First, the code is shorter when written using the some method. That’s not such a big deal; sometimes short code is harder to read. However, in my opinion, it’s actually easier to read the implementation of startsWithVowel. My eye goes straight to some, and I know that method will just look for “some” value which satisfies the condition in the callback function. It’s also important that you’re going to find code like this all over the place, these days. Since you have to know what it means, it helps to use it in order to get comfortable with it.

In my next blog post, I’ll explore the performance differences between the for loop and the Array.some method.

Do you need a portfolio to get a software job?

Of course, you don’t need a portfolio of projects to get a job in software. I’ve gotten all my jobs without a portfolio, and I’m betting the vast majority of software developers are in the same situation.

Assuming that is true, then, is it worth the trouble to build a portfolio?

I came across one very good case study in the freeCodeCamp forum. A Brazilian started studying computer science in 2014. Later (2017), they finished studying at freeCodeCamp, and with some help from their portfolio website, they got a full time job as a full stack developer. This is especially notable because they had some very finicky requirements: only remote positions, only doing full stack or back end work, and so on.

How much was the portfolio a factor? It seems to have been helpful, but it didn’t seal the deal. The person said that they got plenty of interviews, but the result was always: “Great portfolio, but we need someone with more experience”. After this happened too many times, they stopped emphasizing their portfolio work, and instead began to focus on soft skills (knowledge sharing, consistency, meeting deadlines, etc). When they finally got a job, they said, “The person who hired me mentioned that the reason they wanted me over someone they knew and/or had more experience was basically because i paid attention to their job announcement and had proof that i was a self learner.”

That’s a nice anecdote. It supports the idea that a portfolio can help get your foot in the door. I’ve found some threads on Hacker News where hiring managers make claims that they both do, and do not, pay attention to developer portfolios when hiring.

Here is a list of “developer portfolio” links on HN over the years:

(1) Hello HN: I am quitting school for freelance, here’s my portfolio (Dec 7, 2010)

(2) Ask HN: With nothing but an open-source portfolio, how to start job-hunting? (Feb 4, 2017)

(3) Ask HN: What portfolio items are most impressive to you when hiring developers? (May 25, 2017)

(4) Build your portfolio by working on interesting projects (Mar 28, 2015)

(5) Show HN: My first portfolio site – Full Stack Engineer (May 15, 2015)

(6) Ask HN: Does a college degree hold more power than a strong portfolio? (Jun 5, 2015)

(7) Ask HN: Beginning freelance web developer: no clients – portfolio? (Apr 29, 2011)

(8) Ask HN: What makes a great freelance portfolio? (Jun 9, 2014)

If you’re planning on building a portfolio, I think you’ll want to thoroughly read each of the threads above. Below are some informative snippets that will give you a general idea of what I discovered.

In this HN thread, user ivanzhao presented his portfolio as an example of his skills. He got some feedback, both harsh and helpful, from the crowd at HN. Critiques recommended that he validate his site, that mouseover events are not usable on mobile devices, and that the site was not responsive. He got several remarks from users who said they’d probably never hire him based on their distaste for his portfolio, but there were also several remarks requesting his contact info and a rate! Note that this dude is the founder of Notion – so he went from quitting grad school in 2010 to founding Notion (circa 2013), which is a pretty cool story!

In a different thread, a high school student had worked on “open-source projects to create a portfolio demonstrating proficiency with a range of tools, languages, services, and paradigms”. The student wondered how this corpus could be leveraged to get a job. a-saleh indicated that he found starter jobs using family and friends (apparently no portfolio was involved). kafkaesq recommended accepting student work, even if it’s “for peanuts”, and trying to aim for work that can go into a portfolio. chetanbhasin said “Luckily, for most Software engineering roles, a good portfolio is far more important than an obscure number for the years you have worked.” ps5 gave support for having a portfolio, saying “Build and host a web app that uses some real-time public-facing data… That’s how I got a job as a very junior developer.” innocentoldguy confirmed this: “My company recently hired a young student right out of high school. What made him stand out was a few apps he had published on the App Store…” DEinspanjer expressed interest in looking at the student’s portfolio if it included work in Angular. eli said that they’ve hired “several people with no formal experience, but some awesome open source work.” So there are several posts in this thread which suggest that a portfolio project is useful for entry-level or junior-level positions. Other people in the thread suggest that it’s far better to get a college education rather than aim for work straight out of high school. The entire thread is definitely worth reading if you are looking to break into software development or web development, even if you’re not a high school student.

In another HN thread, someone asks “What portfolio items are most impressive to you when hiring developers?” Now things get more interesting! kasey_junk asserts “The best devs I know dont have portfolio pieces. They tend to work on problems that the people employing them pay a lot of money to prevent being public…So for me portfolios are for junior devs & graduate students looking to leave academia…” Later, they said that they mostly use “network based hiring” (i.e. it’s not what you know, but who you know!). corobo indicates that they do find portfolios useful when hiring, and concludes “Associated blog posts that explain how your code works and why though? I’d put your name to the top of the “get this person in” list on the spot“. edoceo appears to find portfolio projects useful when hiring and says “I’ll also look at your wiki and issues, to evaluate communication.

In this other HN thread, iandanforth says they’re hiring and would definitely like to see a code portfolio in evaluating candidates. And here’s a comment from yet another HN thread where portfolios are discussed: eranation says they pay attention to portfolio work when hiring for a specific task or language, but are more interested in seeing a breadth of experience (CS degree) when the work involves algorithms and data structures. In the same thread, morgante says that as a hiring manager, they consider someone with a strong portfolio and a CS degree to be a stronger candidate than someone without the portfolio.

A contrary opinion comes from tptacek, a user with a good reputation at Hacker News. He says, “If you’re aiming for the most lucrative work, the conversation you want to be having with prospective clients has very little to do with anything you’d put on a developer portfolio, and a lot more to do with (a) being able to speak the language of business (ie: making a credible benefits-focused pitch and understanding how ‘customer service’ principles apply to our kind of work) and (b) being able to tailor a case study or two to a client.” That doesn’t sound like total condemnation of having a portfolio, though… Just that it’s not the #1 thing to focus on.

It could be that I have a little bit of a bias, but my impression is that the software community does consider a portfolio to be a plus when looking to hire a developer, especially for freelance and/or more entry-level work. If you have no trouble getting work, then it may not be worth putting the time in to build a portfolio. If you feel like you could use a boost in your job search, but can’t figure out what kind of project to work on, you may want to read through all the above links at Hacker News! You can also take a look at my list of potential portfolio projects for some ideas to get started.

editing React files in VS Code results in a Parsing error

Yesterday, I wrote about how I’ve tentatively switched over from Sublime Text editor to VS Code for my projects. Later, I started working on a JavaScript file, and realized that I was missing Sublime’s linter. So I turned on linting in VS Code by following the instructions in the VS Code marketplace for Dirk Bauemer’s ESLint.

Immediately, I got a complaint when I viewed a React file with an import statement at the top, like this:

import React from "react";
...

The word import had a squiggly red line under it. When I hovered over that, I saw the error message “Parsing error: The keyword ‘import’ is reserved eslint”. Like this:

Parsing error: the keyword 'import' is reserved

I found a git issue comment which explained how to fix it (for me! YMMV). Here’s how I did it.

First, I had to install ESLint-plugin-React: npm install -g eslint-plugin-react --save-dev

Then, I had to edit my VS Code json.settings. Here’s how: From the top menu, click File > Preferences > Settings. Your User and Workspace Settings area opens up, and there’s a handy search box at the top. Type in eslint and you’ll see a bunch of search results, including some links to “Edit in settings.json“. Click that link, and your settings.json file opens up. This is just a text file! For me, it is located under my home directory, in .config/Code/User/settings.json (I’m using Ubuntu 16.04). I got confused when I noticed that there was a settings.json file under the node_modules directory for my React project, as well (./node_modules/detect-port-alt/.vscode/settings.json). Don’t get distracted by additional files with that name. Just use the file which is shown by VS Code using the above procedure.

My json.settings originally looked like this:

{
    "editor.formatOnPaste": true,
    "editor.formatOnType": true,
    "editor.insertSpaces": false,
    "editor.detectIndentation": false,
    "editor.wordWrap": "on",
    "eslint.trace.server": "messages",
    "eslint.options" : {
        "useEslintrc": false
    }
}

All I had to do was add a new sub-option under eslint.options, as described in the git comment, like this:

{
    "editor.formatOnPaste": true,
    "editor.formatOnType": true,
    "editor.insertSpaces": false,
    "editor.detectIndentation": false,
    "editor.wordWrap": "on",
    "eslint.trace.server": "messages",
    "eslint.options" : {
        "useEslintrc": false,
        "parserOptions": {
            "ecmaVersion": 7,
            "sourceType": "module",
            "ecmaFeatures": {
                "jsx": true,
            }
        }
    }
}

VoilĂ ! The linting error went away immediately; I didn’t have to reload the project or restart VS Code.

sublime compared with vs code

There’s a pretty good discussion in the Sublime Forum comparing Sublime with VS Code. Here’s my two cents.

I first started programming in JavaScript when my primary job was in Java development. My IDE was Eclipse, which was used by everyone in the company. I would occasionally have to tweak some JavaScript code. And Eclipse worked fine for that.

Later, I started working full time on a rather large Node.js codebase. One of my JavaScript developer friends highly recommended Sublime. I wound up using that code editor for years. I’m too embarrassed to say how long it took me to pay for a license, but eventually, I did. Kudos to the Sublime crew for building a very solid product!

Last year I went to a meetup where a demo was done in VS Code. It looked okay, but I was skeptical… It’s a Microsoft product, and it’s free? What’s the hitch? I was happy enough with Sublime, so while I did try out VS Code, very briefly, I didn’t switch.

It was only a few months later that I heard from my JavaScript developer friend – he had switched to VS Code! I decided to try it. The switch from Sublime to VS Code was very easy, and I’ve been using it for a few months now.

I can’t exactly explain why, but I think the main reason I stuck with it is that Sublime is sometimes unresponsive, whereas VS Code is snappier. However, I’ve noticed that other developers complain that VS Code can be slow for them, so maybe there’s some peculiarity on my system (Ubuntu) which causes that.

I like the “look and feel” of VS Code better than Sublime. I get the impression that it does code completion better than Sublime, but I don’t actually have any facts to back that up.

On the other hand, I have a few problems with VS Code. It has a weird way of forgetting my word wrap settings. I’ll be editing a text file and use Alt-z to wrap text and everything’s good to go. Then I close VS Code, and the next time I open it, my word wrap setting is gone and I have to redo it. Not cool! I also prefer the way that you “quick switch” workspaces in Sublime. But these are minor quibbles.

I’m not convinced that VS Code is the wave of the future. And I’m still waiting for a bomb from MS to drop (“oops we’ve decided to charge a $500 subscription now that you’re hooked on VS Code!”). I may switch back to Sublime, sooner or later.

Some others have switched from Sublime to VS Code: Nick Janetackis, Zell Liew, Mike Herchel, and others. Andrew Davis gives some good reasons for sticking with Sublime (mostly about working on PHP code, and I agree with him there, I think Sublime rocks for editing PHP).

My main reason for not switching code editors up until now is that I prefer to spend as little time tinkering with dev tools as possible. As a fullstack dev, I already have plenty of excitement dealing with multiple technologies on a regular basis. When I’m working, I want to spend time getting stuff done. I do recognize that little inefficiencies can really add up to less productivity in the longer term, though! So it’s good to explore new tools once in a while. Spending the time now to tweak a tool, or learning how to switch over to a new one, may eventually save you time in the long run.