C++写node笔记(四)

2012-11-30 17:42

C++写node笔记(四)

by snoopyxdy

at 2012-11-30 09:42:00

original http://snoopyxdy.blog.163.com/blog/static/601174402012103092114682

分析了官网的示例之后,我想试着写点简单点的东西,尝试下node的c++的addon的写法。
从简单的入手,新建一个文件夹,取名为verify,我打算从简单的但是实用的node验证模块入手,写一个C++的验证模块。本文只是开了个头,做一些简单的示例。
文件夹的目录:

verify

/index.js

/package.json

/readme.md

/lib

/verify.js

/addon

/binding.gyp

/SimpleVerify.cc

/SimpleVerify.h

/verify.cc

一个简单的模块目录构成,不知道写的对不对,反正我就这么弄了,哈哈。
我们直接看下3个c++addon代码:(依葫芦画瓢的,不要取笑啊)

verify.cc:

#define BUILDING_NODE_EXTENSION
#include <node.h>
#include "SimpleVerify.h"
using namespace v8;



void Init(Handle<Object> target) {

target->Set(String::NewSymbol("isArray"),
FunctionTemplate::New(SimpleV::isArray)->GetFunction());

target->Set(String::NewSymbol("isNumber"),
FunctionTemplate::New(SimpleV::isNumber)->GetFunction());
}

NODE_MODULE(verify, Init)


SimpleVerify.h

#ifndef SV_H
#define SV_H
#include <node.h>

class SimpleV {
public:
static v8::Handle<v8::Value> isArray(const v8::Arguments& args);
static v8::Handle<v8::Value> isNumber(const v8::Arguments& args);

private:
SimpleV();
~SimpleV();
};

#endif


SimpleVerify.cc

#define BUILDING_NODE_EXTENSION
#include <node.h>
#include "SimpleVerify.h"

using namespace v8;

SimpleV::SimpleV() {};
SimpleV::~SimpleV() {};

Handle<Value> SimpleV::isArray(const Arguments& args) {//定义是否是数组
HandleScope scope;
return scope.Close(Boolean::New(args[0]->IsArray()));
}

Handle<Value> SimpleV::isNumber(const Arguments& args) {//定义是否是数字
HandleScope scope;
return scope.Close(Boolean::New(args[0]->IsNumber()));
}


代码很简单,目前SimpleV类只有判断是否是数组和是否是数字2个方法,这2个方法都可以在v8手册上看到,当然我打算继续完善这个模块,根据node-validate的功能山寨一把,全部搬成C++的。
估计有同学说,你费这么大劲搞c++的验证模块,到底效果如何?有用吗?
数据说明一切,下面我们针对这2种情况做一下简单的测试,测试代码如下:

var sv = module.exports = require('./lib/verify.js');

//利用纯js语法进行判断
var ia = Array.isArray;
console.time('js');
for(var j=0;j<1000;j++){
ia([]);
ia('111');
isNaN(123);
isNaN('abc');
}
console.timeEnd('js')


//利用c++模块进行判断
var ia2 = sv.isArray;
var in2 = sv.isNumber;
console.time('c++');
for(var j=0;j<1000;j++){
ia2([]);
ia2('111');
in2(123);
in2('abc');
}
console.timeEnd('c++');

测试环境:linux虚拟机,不多介绍了,具体测试结果可能跟机器配置有关系
我们看一下多次测试的结果:

js: 10ms
c++: 3ms


js: 9ms
c++: 1ms


js: 7ms
c++: 2ms


js: 8ms
c++: 0ms


js: 6ms
c++: 0ms

我们可以看到尽管我们利用了js原生的isNaN和isArray这2个方法,但是从性能上来说,无疑C++验证的更快一些。
可能有同学说循环1000次是否有些过了,但是我最近打算用node做接口服务,所以同时有100个接口被查询,每个接口有5-10个参数被验证的情况还是可能存在的,如果我们使用c++的addon验证模块可以至少快5ms相应给用户,当然如果一些正则等等判断可能差距的更多。

最后补一个小教训,我在一开始先创建了binding.gyp,没有把SimpleVerify.cc文件包含进去,导致每次编译都通过,但是调用一直报错,搞了好一阵子才发现,给大家提个醒啊,不要像我这么笨了,哎~