高性能的算法库通常都是用C/C++编写。当你想要用JavaScript来开发条形码商业应用,你有两个选择:1.通过node-gyp来编译一个Node.js C/C++扩展。2.把C/C++代码编译成WebAssembly。这里基于Dynamsoft Barcode Reader来做一个比较。
序列号
申请一个免费试用的序列号。
安装
-
WebAssembly SDK
npm i dbrjs
特点对比
速度
开发应用,性能至关重要。毫无疑问,C/C++的扩展性能肯定更好。不过WebAssembly的差距到底要多大,要测试过才知道。
下载编译Dynamsoft Barcode Reader Node.js扩展:
cd src
node-gyp configure
node-gyp build
创建一个简单的条形码应用:
var dbr = require('./build/Release/dbr');
var Module = require('dbrjs');
function decodeFileStreamAsync(fileName) {
let stats = fs.statSync(fileName);
let fileSize = stats["size"];
fs.open(fileName, 'r', function(status, fd) {
if (status) {
console.log(status.message);
return;
}
var source = fs.readFileSync(fileName);
var typedArray = new Uint8Array(source);
Module.onRuntimeInitialized = function() {
let dbr = new Module.BarcodeReaderWasm("t0068NQAAAKTSQDbEid8CTEeNluhTXi+h35G8R03xIHsyYNzZoa2GiU2a8y7s5Z1lfHsMW5dNyZmH6jQL51HUcoB5EhpDeDk=");
console.time('wasm');
let results = dbr.DecodeFileInMemory(typedArray, "");
console.timeEnd('wasm');
let json = JSON.parse(results);
let barcodeResults = json['textResult'];
let txts = [];
for (let i = 0; i < barcodeResults.length; ++i) {
console.log("Value : " + Buffer.from(barcodeResults[i].BarcodeText, 'base64').toString('ascii'));
}
console.log("Done............................................................\n");
};
let buffer = new Buffer(fileSize);
fs.read(fd, buffer, 0, fileSize, 0, function(err, bytesRead, data) {
console.time('native');
dbr.decodeFileStreamAsync(buffer, fileSize, barcodeTypes, function(err, msg) {
console.timeEnd('native');
let result = null;
for (index in msg) {
result = msg[index];
// console.log("Format: " + result['format']);
console.log("Value : " + result['value']);
}
console.log("Done............................................................\n");
}, "");
});
});
}
运行之后可以看到性能差异:
WebAssembly耗时是C++扩展的3倍。
可移植性
虽然Node.js C/C++扩展的性能占优,但是在不同平台上必须重新编译,这样非常麻烦。而WebAssembly是没有这个问题的。在Windows上安装Linux子系统可以快速测试。
Web应用开发
如果要做Web应用开发。Node.js的扩展只能用于服务端,而WebAssembly既可以用在服务端,也可以用在网页客户端。部署在服务端就需要通过HTTP来通信,这样如果要做一个网页条形码应用,就需要不断发送数据,解码,再返回结果。很显然这样的效率是不如网页客户端直接做条形码检测的。
WebAssembly条形码开发示例
Node.js
创建index.js:
const fs = require('fs');
var source = fs.readFileSync('test.jpg');
var typedArray = new Uint8Array(source);
const Module = require('dbrjs');
Module.onRuntimeInitialized = function() {
let dbr = new Module.BarcodeReaderWasm("t0068NQAAAKTSQDbEid8CTEeNluhTXi+h35G8R03xIHsyYNzZoa2GiU2a8y7s5Z1lfHsMW5dNyZmH6jQL51HUcoB5EhpDeDk=");
console.time('wasm');
let results = dbr.DecodeFileInMemory(typedArray, "");
console.timeEnd('wasm');
let json = JSON.parse(results);
let barcodeResults = json['textResult'];
let txts = [];
for (let i = 0; i < barcodeResults.length; ++i) {
txts.push(Buffer.from(barcodeResults[i].BarcodeText, 'base64').toString('ascii'));
}
console.log(txts.join(", "));
};
运行:
node index.js
Web
var reader;
c.onRuntimeInitialized = function () {
document.getElementById('anim-loading').style.display = 'none';
buttonFile.disabled = false;
buttonVideo.disabled = false;
reader = new c.BarcodeReaderWasm("t0068NQAAAKTSQDbEid8CTEeNluhTXi+h35G8R03xIHsyYNzZoa2GiU2a8y7s5Z1lfHsMW5dNyZmH6jQL51HUcoB5EhpDeDk=");
};
if (reader) {
try {
// results = reader.DecodeBuffer(idd.buffer, imageWidth, imageHeight, imageWidth * 4, 7, "");
let results = reader.DecodeFileInMemory(arrayBuffer, "");
let json = JSON.parse(results);
let barcodeResults = json['textResult'];
let txts = [];
for (let i = 0; i < barcodeResults.length; ++i) {
txts.push(b64DecodeUnicode(barcodeResults[i].BarcodeText));
}
barcode_result.textContent = txts.join(", ");
} catch (e) {
console.log(e);
}
}
结论
如果你要开发服务端的应用,而且追求性能,选择Node.js C/C++扩展
。如果不是太在意性能上的那点差异,WebAssembly
肯定是最佳选择。
源码
https://github.com/dynamsoft-dbr/webassembly