{"provider_url": "https://medium.com", "description": "To begin my first writing on a technical subject, I must say I don't like writing. I prefer to speak to a camera and microfone, but I thought this could worth a try. Well, I love NodeJS, but I love Logic too.", "embeds": [], "safe": true, "provider_display": "medium.com", "related": [], "favicon_url": "https://cdn-static-1.medium.com/_/fp/icons/favicon-medium.TAS6uQ-Y7kcKgi0xjcYHXw.ico", "authors": [], "images": [{"caption": null, "url": "https://cdn-static-1.medium.com/_/fp/img/default-preview-image-v2.MXL-j6S8fTEd8UFP_foEEw.png", "height": 1126, "width": 1126, "colors": [{"color": [248, 251, 250], "weight": 0.7827148438}, {"color": [0, 228, 121], "weight": 0.1389160156}, {"color": [0, 169, 110], "weight": 0.0783691406}], "entropy": 0.811434093896, "size": 5634}, {"caption": null, "url": "https://cdn-images-1.medium.com/max/800/1*aeWo6e6FC8InJwBl3TmpDw.jpeg", "height": 342, "width": 800, "colors": [{"color": [129, 188, 73], "weight": 0.9597167969}, {"color": [244, 251, 247], "weight": 0.040283203100000005}], "entropy": 1.0014682286, "size": 16860}, {"caption": null, "url": "https://cdn-images-1.medium.com/max/800/1*WxHM17mrtnIu8dxYYPx9gg.png", "height": 489, "width": 800, "colors": [{"color": [246, 250, 251], "weight": 0.7883300781}, {"color": [0, 70, 109], "weight": 0.2116699219}], "entropy": 1.2076254722, "size": 54840}, {"caption": null, "url": "https://cdn-images-1.medium.com/max/800/1*gqISGcDMXDqIxnQirzFGeg.png", "height": 369, "width": 800, "colors": [{"color": [245, 249, 250], "weight": 0.7961425781}, {"color": [0, 80, 123], "weight": 0.2038574219}], "entropy": 1.6326465653, "size": 77445}, {"caption": null, "url": "https://cdn-images-1.medium.com/max/800/1*9IX5MWrnaCBzzeS3h5N2oA.png", "height": 369, "width": 800, "colors": [{"color": [0, 53, 83], "weight": 0.8039550781}, {"color": [234, 239, 242], "weight": 0.1960449219}], "entropy": 3.0509671119, "size": 92123}], "cache_age": 84895, "language": "English", "app_links": [{"type": "android", "namespace": "ai", "app_name": "Medium", "app_store_id": "828256236", "package": "com.medium.reader"}, {"url": "medium://@ndaidong/setup-rocket-chat-within-10-minutes-2b00f3366c6", "type": "ios", "namespace": "ai", "app_name": "Medium"}, {"url": "medium://@ndaidong/setup-rocket-chat-within-10-minutes-2b00f3366c6", "type": "android", "namespace": "ai"}, {"url": "https://medium.com/@ndaidong/setup-rocket-chat-within-10-minutes-2b00f3366c6", "type": "web", "namespace": "ai"}, {"url": "medium://@ndaidong/setup-rocket-chat-within-10-minutes-2b00f3366c6", "namespace": "twitter", "type": "iphone", "name": "Medium", "id": "828256236"}, {"path": "https/medium.com/@ndaidong/setup-rocket-chat-within-10-minutes-2b00f3366c6", "package": "com.medium.reader", "namespace": "google", "type": "android"}], "original_url": "https://medium.com/@ndaidong/setup-rocket-chat-within-10-minutes-2b00f3366c6", "url": "https://medium.com/@ndaidong/setup-rocket-chat-within-10-minutes-2b00f3366c6", "media": {}, "title": "Setup Rocket Chat within 10 minutes", "offset": null, "lead": null, "content": "
\n

To begin my first writing on a technical subject, I must say I don't like writing. I prefer to speak to a camera and microfone, but I thought this could worth a try.

\n

Well, I love NodeJS, but I love Logic too. and sometimes, we must stop what we are doing and ask ourselves: What the HECK is going on under the carpet?

\n

I'm in the middle of a Robotics Project, where 3 robots will play football autonomously, and their position will be discovered in real time from a Camera in the top of the field. The positions of the robots, target locations and everything are VECTORS.

\n

Vectors are a N-Dimensional way of storing values. Basically, if you say your sofa is your main spot, that's [0, 0] in a 2D space, or [0, 0, 0] in 3D. If you go 1m to the left, you might say you are at [-1, 0] if the 1st index is Left/Right and Left is Negative.

\n

So, I began structuring the Data and implementing basic methods (sum, multiplication, cros-product). And, I asked myself:

\n

What is more efficient: To store states (x, y, z..) in Arrays or Objects?

\n

This question was really important because Vectors are used many times every second: 60FPS * 3 Robots * 2000 = 360.000 (estimated calculations).

\n

My first thought, as a C/C++ programmer was: For sure, Arrays. And I was wrong, 1.4x in the opposite direction.

\n

Benchmark Object/Array with two elements

\n

The test was: Is storing and sum X an Y in an array [X, Y], better than in an Object: {x: xValue, y: yValue}?

\n

I wrote a simple program. A \"makeItBurn\" function which runs a desired method for a big number of times and logs the time spent.

\n
  let timeEnd = Date.now()
let duration = (timeEnd - timeStart)
console.log(`Stress test on ${name}: ${duration} ms`)
}
\n
makeItBurn('sumVectorObject', sumVectorObject);
makeItBurn('sumVectorArray', sumVectorArray);
\n

The output was:

\n
// 100000000 Repetitions
Stress test on sumVectorObject: 4500 ms
Stress test on sumVectorArray: 6302 ms
\n

The difference was so clear, that I tested them in many ways, and even inverted the call to make sure it wasn't a garbage collector problem or so.

\n

At that moment, I had something right in my mind:

\n
DO NEVER USE ARRAYS TO STORE VECTORS JUST BECAUSE YOU CODE IN C++ AND THINK IT'S FASTER.
\n
(My Mind)
\n

Although I could have stopped there, I started to wonder if in fact, everything was true in my life. Maybe I'm upside down and I don't know it because I'm too sure I'm not.

\n

And I made another test, a test that should at least let me die in peace, but it just made me look more intrigued:

\n
const sumVectorObjectLikeArray = () => {
let a = {0: Math.random(), 1: Math.random()}
let b = {0: Math.random(), 1: Math.random()}
let c = {0: a[0] + b[0], 1: a[1] + b[1]}
return c;
}
\n

Just a mix of both, in an attempt to trick NodeJS, using an Object as a Mapping table for X/Y (But not being an Array). If Objects are proved to be Faster than Arrays with small elements, then accessing it's '0' and '1' index should be the same as accessing 'x' and 'y'.

\n

No. It is not. And it's ~ 28x slower:

\n
Stress test on sumVectorObjectLikeArray: 122732 ms
\n
DO NOT USE OBJECTS AS ARRAYS, NODEJS WILL HATE YOU FOR THAT.
\n
(My Mind, again)
\n

Is yellow really yellow?

\n

I wasn't sure anymore. Crazy things happens, but it was far beyond from crazy when my MacBook almost flew for two minutes.

\n

It led me to the last benchmark testing, in something I use all the time: Mapping Lists.

\n

I use them all the time to \"optimize\" algorithms. One example is: I have a list of \"Comments\" with each user Id, and I want to know how many comments each user has there. I like doing sort of this way when I can't doit directly in database:

\n
let comments = [{userId: 321, ...}, {userId: 321, ...}, ...]
let commentUserIds = comments.map(c => c.userId)
\n

I wrote three tests for it:

\n

And the results:

\n
// 100 Repetitions
Stress test on mapTableArray: 2881 ms
Stress test on mapTableObject: 659 ms
Stress test on mapTableObjectStr: 1623 ms
\n

But at least that time I was right... Much faster access than a normal array. But you know why I will keep using it? Because I tested it.

\n

So what?

\n

This post is not to encourage you to hate NodeJS or any other language. In fact I have never done benchmarks myself before (I appreciate feedbacks). It is more of a way to make you dig deeper into things, because the magic behind it isn't yours. After all that, this situation made me go to the forth step:

\n
What else can be different than what I think, and I'm happily using without testing? Everything.\n
\n
", "entities": [], "favicon_colors": [{"color": [0, 0, 0], "weight": 0.4978027344}, {"color": [0, 229, 119], "weight": 0.3171386719}, {"color": [0, 170, 110], "weight": 0.1850585938}], "keywords": [{"score": 53, "name": "array"}, {"score": 52, "name": "testing"}, {"score": 40, "name": "nodejs"}, {"score": 31, "name": "stress"}, {"score": 30, "name": "makeitburn"}, {"score": 30, "name": "sumvectorarray"}, {"score": 30, "name": "userid"}, {"score": 30, "name": "sumvectorobject"}, {"score": 29, "name": "vectors"}, {"score": 28, "name": "objects"}], "published": null, "provider_name": "Medium", "type": "html"}