PostsAboutGames
All posts tagged with node

Bubble Sort Benchmark in Rust

July 01, 2020 - Søren Alsbjerg Hørup

One of my colleagues have updated my Bubble Sort Benchmark with a Rust implementation, and the results are in!

> ./start.bat

> clang -O -fsanitize=address main.cpp   && a.exe
   Creating library a.lib and object a.exp
30125ms to sort 50000 elements 10 times (Vector)
22985ms to sort 50000 elements 10 times (Array)

> clang -O main.cpp   && a.exe
10281ms to sort 50000 elements 10 times (Vector)
9906ms to sort 50000 elements 10 times (Array)

> dotnet run --configuration=Release
32547ms to sort 50000 elements 10 times  (List)
15531ms to sort 50000 elements 10 times (Array)

> node index.js
28133ms to sort 50000 elements 10 times

> rustc -O main.rs -o rust.exe

> rust.exe
Took: 10.5915778s to sort 50000 elements 10 times

As seen, sorting 50k elements 10 times took 10.59 seconds using Rust. The C++ implementation was a tad faster at 9.9 seconds when using C arrays and 10.28 seconds when using std::vector. However, the C++ implementation does not guarantee against memory corruption, which is the case with Rust. The paid memory safety overhead of 3-7% in Rust, is in my opinion worth it.

Comparing the address sanitized version of the C++ array implementation, Rust is twice as fast fast: 10.59 vs 22.98 seconds. I believe this is due to the implementation of the sanitizer in clang, i.e. it needs protect every memory access, since C++ allows pointer arithmetic. Rust does not allow such programming behavior, unless wrapped in unsafe {}.

Compared with the node and DotNet core implementations of Bubble sort, the Rust implementation is between 50% (DotNet Array) and 300% (DotNet List) faster, which again is not surprising due to the restrictions of the Rust language: which allows for tight optimizations without introducing runtime checks (except for array out of bounds).

Rust is an awesome language and I definitely hope to see it succeed!

Apache Thrift - not a replacement for Protobuf *yet*

April 23, 2019 - Søren Alsbjerg Hørup

I frequently need to share typed structures between applications, such as between an ASP.NET C# Backend and an Typescript React single page application.

For this, I have used Google’s protobuf, a binary serialization library.

In protobuf, one defines the intended information in .proto files and uses a Protobuf compiler to auto generate language specific source files.

syntax = “proto3”; message Position { float x = 1; float y = 2; }

Here I define a message called Position, containing two simples float values: x and y. 1 and 2 denotes the order of which the fields appear during the serialization process - for backward compatibility reasons changing the name is allowed but changing the numbers are not since this will change the order on the wire!

Using a Protobuf compiler, such as protoc, language specific versions of the messages can be generated to fit the required language. For C#, the message above results in a class called Position with public Properties called X and Y, including several serialization methods and Properties such as WriteTo, MergeFrom and Parser.

For the web, protobufjs exists, which is a protobuf compiler implemented in JavaScript. This compiler can generate JavaScript and TypeScript source files to be consumed both in node.js and in the browser. I typically generate files for node.js and use a bundler such as parcel-bundler or webpack to bundle for the browser.

This provides binary transport of my messages from backend to frontend, with type security - very nice indeed.

Lately, I have looked into Apache Thrift, which is very similar to Protobuf but with support for many more programming languages out of the box, and with the added bonus of also supporting Remote Procedure Calls (RPC) . (although RPC can be achieved in Protobuf using gRPC)

The syntax of Thrift messages are very similar to Protobuf, the same message above would be written as:

struct Position { 1: double x, 2: double y }

Note: floats are not supported by Thrift, only doubles.

Looking at the supported languages, it seems to dwarf that of protoc (the default compiler of Protobuf) - with support for nearly 30 languages of the the box. Very nice indeed.

C# and TypeScript is also supported, making the Thrift a prime candidate for my typical needs. However, diving a bit deeper into what support means, it quickly shows that not all languages are equally supported, this includes TypeScript.

Generating browser compatible TypeScript that supports binary serialization is not supported. Node.js compatible TypeScript can be generated that supports binary serialization, but this generated code cannot be consumed by bundlers such as WebPack or Parcel Bundler. RPC is also not supported in the browser, although not required for the project in which I decided to test out Thrift.

Looking through NPM, I found “browser-thrift” - a patched version of node thrift that can be consumed by bundlers, only requiring that require(‘thrift’) is replaced with require(‘browser-thrift’) in generated thrift code.

After a few tries, I never got this approach to work and reverted back to using Protobuf.

Summary: Binary serialization is not natively supported by Thrift in the browser - making Protobuf the obvious choice until this is implemented in Thrift.

Node on Raspberry PI

March 15, 2017 - Søren Alsbjerg Hørup

I recently re-installed a PI with NodeJS support and MariaDB support.

NodeJS is not known by apt-get (a strange beta/alpha version is present, version 0.10 or something, not what we want).

I found this guide for the job: http://thisdavej.com/beginners-guide-to-installing-node-js-on-a-raspberry-pi/

More or less, execute the script located at deb.nodesources using:

curl -sL https://deb.nodesource.com/setup\_7.x | sudo -E bash -

and then proceed with apt-get install

sudo apt-get install nodejs

Simply as that!

Tagged: linux node

Shared Modules between Node and Browser

January 25, 2017 - Søren Alsbjerg Hørup

I am currently prototyping a game built using TypeScript + Node. Node will host some REST API’s + act as HTTP server + act as WebSocket server. The HTTP server part will host a React frontend also built using TypeScript.

What I want is the ability to share TypeScript code between the two parts of the application.Typically, I have always used outFile when working with React in the browser, because I find it very easy to embed into my index.html. This approach is however not feasable on the server side (it can be hacked, but is ugly as hell), since the server needs to import modules from node_modules using the ES6/TypeScript import syntax.

TypeScript supports the ability to emit ES5 JavaScript code using different module types, such as AMD, systemjs, etc. For this project I have experimented in using modules on both the server and the client portion of my code.

My structure is as follows:

  • /client contains all client related .ts files
  • /server contains all my server related .ts files
  • /library contains all my shared .ts files

This setup allows me to easily import modules from library in either client or server:

import someClass from "../library/someClass";

/client and /server has their own tsconfig.json file which tells the compiler on how to emit JavaScript code. On the /client, I have specified that I want to emit ‘AMD’ modules while on the /server I want to emit commonJS used by node.

When building, I invoke tsc on both /client and /server, which will emit more or less the same JavaScript output but where the module format differs. In the browser, I can easily include the AMD module loader and load all my stuff. I can even concatenate the output of the client (for my own modules) using outFile if I make sure to manually load the output in the browser before passing everything to the AMD module loader.

On the server, Node can use commonJS and require to load my modules without any issue, since I built the node part using commonJS as module loader.

The only con I have found is that /library directory gets compile twice, which is OK in my book since we are talking about different run-time environments (node vs the browser).

I need to test this setup a bit more, and see if it scales as well as I hope!

Visual Studio Code and Source Maps

January 20, 2017 - Søren Alsbjerg Hørup

It has been some time since I last required vscode’s JS debugging functionality. Today I ran into an issue using the latest version of vscode + TypeScript source mappings. Specifically, my debugger was unable to find the TypeScript source thus unable to hit any breakpoints.

I have all my TypeScript source saved into the /src folder. tsc compiles and stores the result into the /bin folder along with source mappings between the .js files and the .ts files.

My debugger was unable to locate the source files, even when the js.map files contained the absolute path to my src folder.

Apparently, one has to add outFiles to launch.json with a correct path to the /bin folder for this to work. vscode cannot automatically detect the the presence of map files along the out .js files. This is a bit puzzling, since my launch.json contains the path to the JavaScript file I want to launch.

"outFiles": \["${workspaceRoot}/bin/\*\*.js"\]

This snippet did the trick for me.

And yes! I know that /bin might not be correct naming since JavaScript files are not binary :-)

Apache Cordova

January 17, 2017 - Søren Alsbjerg Hørup

My son is lacking a bit in the language department. To help him get better I decided to implement an app which randomized a set of pictures into a grid of 4 cells. The app tells out loud the name of the object/thing in one of the pictures which he has to pick.

Screenshot of the finished app on Google Play

I decided that I wanted to tryout Apache Cordova (formerly PhoneGap) and build it as an hybrid-app. Apache Cordova can be installed directly from Node’s package manager ‘NPM’:

npm install -g cordova

To create an app, call

cordova create AppName

which will scaffold a Cordova HTML5 app in the folder AppName.

cordova run browser

will build and start the cordova application in a browser.

cordova run android

will build and start the cordova application in an Android environment. The latter requires the android SDK and an attached device or emulator.

One issues I found with Cordova 6.x was that I was unable to create a proper Android build. Assets was not correctly compiled. I reverted to Cordova 5.x which worked perfectly. My guess is that this will be fixed in the next version.