非常に単純なnodejsc++アドオンを作成し、その使用法を通常のnodejsモジュールの使用法(CoffeeScriptで記述)と比較しようとしています。addonからAddonClassの100万個のオブジェクトインスタンスを作成し、モジュールからCoffeeClassを作成するテストを作成しました。ソースコードは次のとおりです。
addon.cpp
#define BUILDING_NODE_EXTENSION
#include <node.h>
#include "addon_class.hpp"
using namespace v8;
static void InitAll(Handle<Object> target) {
Addon::Init(target);
}
NODE_MODULE(addon, InitAll)
addon_class.hpp
#ifndef _ADDON_CLASS_HPP_
#define _ADDON_CLASS_HPP_
#include <node.h>
class Addon : public node::ObjectWrap {
public:
static void Init(v8::Handle<v8::Object> target);
private:
Addon(int value) : value_(value) {};
~Addon() {};
static v8::Handle<v8::Value> New(const v8::Arguments& args);
int value_;
};
#endif
addon_class.cpp
#define BUILDING_NODE_EXTENSION
#include <cstdio>
#include <node.h>
#include "addon_class.hpp"
using namespace v8;
Persistent<FunctionTemplate> tpl;
void Addon::Init(Handle<Object> target) {
Local<FunctionTemplate> t = FunctionTemplate::New(New);
tpl = Persistent<FunctionTemplate>::New(t);
tpl->SetClassName(String::NewSymbol("AddonClass"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
target->Set(String::NewSymbol("AddonClass"), tpl->GetFunction());
}
Handle<Value> Addon::New(const Arguments& args) {
HandleScope scope;
Addon* obj = new Addon(0);
if (args[0]->IsNumber()) {
obj->value_ = args[0]->NumberValue();
}
obj->Wrap(args.This());
return args.This();
}
CoffeeClass.coffee
class CoffeeClass
value: undefined
constructor: (@value) ->
if !@value? then @value = 0
exports.CoffeeClass = CoffeeClass
ベンチマークコーヒー
CoffeeClass = (require './CoffeeClass.coffee').CoffeeClass
AddonClass = (require './build/Release/addon.node').AddonClass
N = 1e6
calculateDiff = (d1, d2) ->
h = parseInt d2.getHours()
h -= parseInt d1.getHours()
m = parseInt d2.getMinutes() + h * 60
m -= parseInt d1.getMinutes()
s = parseInt d2.getSeconds() + m * 60
s -= parseInt d1.getSeconds()
ms = parseInt d2.getMilliseconds() + s * 1000
ms -= parseInt d1.getMilliseconds()
return ms
testCreate = (LC) ->
d1 = new Date()
for i in [1..N]
l = new LC
d2 = new Date()
console.log LC.name, calculateDiff(d1, d2), "ms"
testCreate(CoffeeClass)
testCreate(AddonClass)
このベンチマークの結果は、私にとって非常に奇妙です。
CoffeeClass 34 ms
AddonClass 487 ms
だから、問題は:なぜこの単純なアドオンはとても遅いのですか?そして、もっと重要なことに、それを使って何かをすることは可能ですか?