Skip to content

Factorial in C++ #10

@mateogianolio

Description

@mateogianolio

This post will briefly cover how to write a Node.js addon. Why? If you're dealing with heavy computation algorithms, a C++ implementaion will in most cases be faster than its JavaScript equivalent.

View the full source code for this post.

Algorithm

Here's the factorial algorithm we'll implement (in pseudo-code):

factorial(n):
  if n == 0:
    return 1;
  return n * factorial(n - 1)

binding.gyp

To be able to compile a Node.js addon we have to create a binding.gyp file with our build target:

{
  'targets': [
    {
      'target_name': 'math',
      'sources': ['factorial.cc']
    }
  ]
}

factorial.cc

Create factorial.cc (or name it whatever but make sure it's the same as in binding.gyp). To access Node's v8 engine, include node.h:

#include <node.h>

Implement the algorithm with double precision:

double factorial(double n) {
  if (n == 0)
    return 1;
  return n * factorial(n - 1);
}

Write the binding:

void factorial(const v8::FunctionCallbackInfo<v8::Value>& info) {
  // get first argument with double precision
  double n = info[0]->NumberValue();

  // calculate result
  double result = factorial(n);

  // create a new number containing the result
  v8::Local<v8::Number> Result = v8::Number::New(info.GetIsolate(), result);

  // return result
  info
    .GetReturnValue()
    .Set(Result);
}

Finally, the addon initialization:

void Init(v8::Local<v8::Object> exports) {
  NODE_SET_METHOD(exports, "factorial", factorial);
}

NODE_MODULE(addon, Init)

Building

After completing the above, build your addon with node-gyp (you'll need build-essential):

node-gyp configure build

factorial.js

Create a new file factorial.js. When you've successfully built the addon, it will be located in build/Release/factorial.node. Include it.

var addon = require('build/Release/factorial.node');

Implement the factorial algorithm, this time in JavaScript:

function factorial(n) {
  if (n === 0)
    return 1;
  return n * factorial (n - 1);
}

Let's test if the addon works:

console.log(addon.factorial(10), 'should equal', factorial(10));
// 3628800 should equal 3628800

Success!

That's all for today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions