C++写node笔记(四)

分析了官网的示例之后,我想试着写点简单点的东西,尝试下node的c++的addon的写法。

从简单的入手,新建一个文件夹,取名为verify,我打算从简单的但是实用的node验证模块入手,写一个C++的验证模块。本文只是开了个头,做一些简单的示例。

文件夹的目录:

1
2
3
4
5
6
7
8
9
10
11
verify
/index.js
/package.json
/readme.md
/lib
/verify.js
/addon
/binding.gyp
/SimpleVerify.cc
/SimpleVerify.h
/verify.cc

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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种情况做一下简单的测试,测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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