Konstantin Käfer
kkaefer
node.js extensions
with C++ and V8
C++ is faster than JavaScript.
Is it?
If possible, write it in JavaScript.
JS ⟷ C++ boundary is slow to cross
function() { return Math.floor(133.7 / Math.PI); }
native JS |
~83,333,333 calls/s |
V8 return |
~13,333,333 calls/s |
V8 async |
~1,745,200 calls/s |
thread pool |
~83,682 calls/s (0.1%) |
Why C++?
- V8 is written in C++
- Wrapping existing C/C++ libraries
- Use more threads
The bare minimum
modulename.cpp
Requiring from JavaScript
$ node
> require('./build/Release/modulename.node');
{}
>
Develop with
$ CXX=clang node-waf configure
Also test with GCC
Defining functions
modulename.cpp
HandleScope
cleans up handles created in this function
- Preserve returned value with
scope.Close()
Exporting functions
modulename.cpp
target
is what node.js calls exports
$ node
> var mod = require('./build/Release/modulename.node');
{ theAnswer: [Function] }
> mod.theAnswer();
42
>
Function arguments
modulename.cpp
args
contains elements of type Value
- Cast to specific type with
To*
functions
Callback functions
modulename.cpp
Call
automatically retains arguments
- Don’t forget
HandleScope scope
at the top
The thread pool
- JavaScript is single-threaded
- I/O and CPU in thread pool
- No V8 access from worker!
Passing data to the thread pool
- Not required, just a convention
Persistent
is a Handle
that stays around until diposed of
Worker function
- Function
AsyncWork
is blocking
- Do not use any V8 code, not even variable reads
- Convert values to POD or C++ types and store them in the baton
After function
callback
function is Permanent, need to delete manually
Wrap callbacks in TryCatch
node::FatalException
throws at the top of the event loop
- Catchable with
process.on('uncaughtException', ...)
API design
- Challenge: Synchronous ➞ Asynchronous
- Use
EventEmitter
- Chainable calls
- Instantiating objects vs. functions
- Make it hard to misuse
- Make it feel as “JavaScripty” as possible
node-sqlite3
API
- No
open()
function, new
implicitly opens
- Statements are executed as soon as database is open
- No need to “close” the database
- No callback?
'error'
event on the Database
object
node-blend
API
- Blends two images of the same size
- No need to create objects with
new
if you don’t require state
More documentation
kkaefer