DEV Community

Nahuel Scotti
Nahuel Scotti

Posted on

How to make your Javascript code run faster

A long time ago, in 2011, I wrote my first DNI (Spanish ID) validation script. I did it with ActionScript.

Some years later, after the Flash era, I re-wrote it for Javascript.

Recently, I went into a heavily Functional Programming learning process and as a goal, I propose myself to create a new module applying what I learned.

The result (not following FP paradigm too much I would say) is:

Better DNI

GitHub logo singuerinc / better-dni

The fastest Spanish DNI (NIE / NIF) validation out there.

npm Codacy grade Coveralls github Known Vulnerabilities npm bundle size (minified)

Better DNI

The fastest Spanish DNI (NIE / NIF) validation out there — And lighter: 660 bytes.

Installation

// npm
npm i better-dni
// yarn
yarn add better-dni
Enter fullscreen mode Exit fullscreen mode

Usage

isValid / isNIF / isNIE / ctrlChar

import { isValid, isNIF, isNIE, ctrlChar } from "better-dni";

// validates any type of DNI (NIE or NIF)
isValid("Z7662566Y"); //=> true

// checks if it is a valid NIF
isNIF("06672804K"); //=> true

// checks if it is a valid NIE
isNIE("X1302311M"); //=> true

// returns the control letter in upper case
ctrlChar("X1302311M"); //=> 'M'
ctrlChar("X1302311"); //=> 'M'
Enter fullscreen mode Exit fullscreen mode

Generators

NIF

import { randomNIF, randomNIFWith } from "better-dni";
randomNIF(); //=> '31719111H'

// returns a valid random NIF given the control letter
randomNIFWith("C")
Enter fullscreen mode Exit fullscreen mode

Quickly I found out that there are many modules doing the same…

Replicate what others already did is a little boring, so I changed my goal to

“Create the faster module to validate a DNI”

In this process, I found many ways to improve the speed of the code, although sometimes it looks a bit uglier, some of them made the code twice faster.

Note that you would get better results with newer versions of Node. I think https://jsperf.com is quite good in speed since it runs isolated with just one or two lines of code, but when I tried in “normal” computers with the whole module the difference is quite big. I would say that you should test your code in different environments and see where you can optimize.

Here is what I discovered:

str.substr() vs str.slice()

'0123456789'.slice(-9); // => '123456789'
'0123456789'.substr(-9); // => '123456789'
Enter fullscreen mode Exit fullscreen mode

Winner: slice / x21 faster! / test

toLowerCase() vs toUpperCase()

I have to admit that I have never thought before why would one method be faster than the other. I was looking into the V8 code and looks like https://github.com/v8/v8/blob/master/src/string-case.cc#L16 is the answer to that.

'A'.toLowerCase(); // => 'a'

'a'.toUpperCase(); // => 'A'
Enter fullscreen mode Exit fullscreen mode

This is especially useful if you need to compare two strings.

Before comparing them, better to convert them to lower case.

Winner: toLowerCase / slightly faster / test

Random image related to speed. You need one in all posts. Photo by James Traf on Unsplash

indexOf() vs object prop

const y = 'xyz'.indexOf('y'); // => 1

const y = {x: 0, y: 1, z: 2}['y'] // => 1
Enter fullscreen mode Exit fullscreen mode

Winner: indexOf / slightly faster / test

String concatenation vs Template literals

I don’t know why I imagined that template literals were more complex than a simple string concatenation.

const x = 'x';

'yyy' + x;

'yyy${x}'; // faster
Enter fullscreen mode Exit fullscreen mode

Winner: Template literals / slightly faster / test

Convert to number

parseInt('1234', 10); // => 1234

+'1234'; // => 1234
Enter fullscreen mode Exit fullscreen mode

Winner: +sign / x6.12 faster! / test

Math.floor() vs Bitwise shift

I took some inspiration from this blog post.

Math.floor(1.123456789); // => 1

1.123456789 << 0; // => 1
Enter fullscreen mode Exit fullscreen mode

Winner: Bitwise shift / slightly faster in jsperf but Math.floor() performs better much better in my MacBook Pro. / test

Other tips that could help your code to run faster

Tip 1

Do easy validations first and return as quickly as possible. Take a look at these snippets:

if(someComplexValidation(value) && value.length !== 9) return;
Enter fullscreen mode Exit fullscreen mode

vs

if(value.length !== 9 && someComplexValidation(value)) return;
Enter fullscreen mode Exit fullscreen mode

It’s the same code right? Do the “easy” validation first so your code does not run and return if the first validation does not pass.

Tip 2

Avoid using costly methods like “toUpperCase()” and try to use smart alternatives:

const n = 'XYZ'.indexOf('y'.toUpperCase()); // => 2
Enter fullscreen mode Exit fullscreen mode

vs

const n = 'XYZxyz'.indexOf('y') % 3; // => 2
Enter fullscreen mode Exit fullscreen mode

Tip 3

If you know that you can achieve the same result with different methods, find the one that works better for each specific case:

const x1 = 'xyz'.substr(0, 1); // => 'x'

const x2 = 'xyz'[0]; // => 'x'

const x3 = 'xyz'.slice(0, 1); // => 'x'
Enter fullscreen mode Exit fullscreen mode

I hope this would help you to optimize your code!

Do you want to contribute, make it faster? Open a pull request:

singuerinc/better-dni

Top comments (2)

Collapse
 
martyonthefly profile image
Sylvain Marty

Very interesting, thank you for sharing !

Collapse
 
ranktutorials profile image
Ranktutorials

thanks for sharing!