百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Napa.js ,你确定不需要了解一下吗?

bigegpt 2024-08-04 11:25 2 浏览

Napa.js是干什么的?

Napa.js 是微软开源的一个基于 V8 的多线程 JavaScript 运行环境。它最初被设计用于在 Bing 中开发不影响性能的高度迭代服务, 随着发展,Napa.js 被发现在 CPU-bound 任务中能有效补充 Node.js ,具备在多个 V8 隔离中执行 JavaScript 并在它们之间进行通信的能力。 Napa.js 作为一个 Node.js 的模块公开,它也可以嵌入到没有 Node.js 依赖关系的主机进程中。

概括来讲,Node.js 是异步的,JS 代码执行和事件通知运行在一个线程中,JS 代码中的耗时操作会挤占事件轮询的 CPU 时间。Napa.js 的出现,很好的对这个缺陷进行了补充,将 JS 执行和事件轮询拆分到不同的线程中。

本文介绍 Napa.js 的核心概念,带领大家探索 Napa.js 是如何运转起来的。


Zone

Zone 是 Napa.js 中的核心概念,它是执行 JavaScript 代码的基本单元,所有涉及多线程相关的内容都离不开 Zone 这个概念。一个进程可以包含多个 zone,而每个 zone 又由多个 JavaScript Worker 组成。

在 zone 内部的所有 worker 都是相似的:他们加载相同的代码,几乎以相同的方式处理 broadcast
execute请求,你无法指定执行某一个特定 worker 中的代码。在不同 zone 之间的 worker 是完全不同的:他们加载不同的代码,或者虽然加载相同代码但以不同的策略执行,例如堆栈大小不同、安全策略不同等。应用会利用多个 zone 来加载不同的策略。

有两种类型的 zone:

  • Napa zone - 由多个 Napa.js 管理的 JavaScript worker 组成。Napa zone 内的 worker 支持部分 Node.js API

  • Node zone - 暴露了 Node.js event loop 的虚拟 zone,具有完备的 Node.js 能力

这样划分让你既可以用 Napa zone 处理繁重的计算事务,也可以用 Node zone 处理 IO 事务。同时 Node zone 也是对 Napa zone 无法完整支持 Node API 的一种补充。

以下代码创建了一个包含 8 个 worker 的 Napa zone:

var napa = require('napajs');
var zone = napa.zone.create('sample-zone', { workers: 8 });

以下代码演示如何访问 Node zone:

var zone = napa.zone.node;

在 zone 上可以做两种类型的操作:

1.Broadcast - 所有 worker 执行同样的代码,改变 worker 状态,返回 promise 对象。不过我们只能通过 promise 的返回结果判断执行成功还是失败。通常用 broadcast 来启动应用、预加载一些数据或者修改应用设置。

2.Execute - 在一个随机 worker 上执行,不改变 worker 状态,返回一个包含结果数据的 promise。
execute 通常是用来做实际业务的。

Zone 的操作采用“先进先出”的策略,但 broadcast比 execute优先级更高。

以下代码演示了使用broadcast和execute完成一个简单的任务:

function foo() { console.log('hi');
}// This setups function definition of foo in all workers in the zone.zone.broadcast(foo.toString());// This execute function foo on an arbitrary worker.zone.execute(() => { global.foo() });

数据传输

由于 V8 不适合在多个 isolate 间执行 JavaScript 代码,每个 isolate 管理自己内部的堆栈。在 isolate 之间传递值需要封送/拆收(marshalled/unmarshalled),载荷的大小和对象复杂度决定着通信效率。所有 JavaScript isolate 都属于同一个进程,且原生对象可以被包装成 JavaScript 对象,我们尝试在此基础上为 Napa 设计一种高效传输数据的模式。

为了实现上述模式,引入了以下概念:

  1. 可传输类型

可传输类型是指可以在 worker 中自由传输的 JavaScript 类型。包括

  • JavaScript 基础类型:null, boolean, number, string

  • 实现了 Transportable 接口的对象(TypeScript class)

  • 由以上类型构成的数组或对象

  • 还有 undefined

2.跨 worker 存储

Store API 用于在 JavaScript worker 中共享数据。当执行 store.set 时,数据被封送到 JSON 并存储在进程的堆栈中,所有线程都可以访问;当执行 store.get 时,数据被拆收出来。

以下代码演示如何利用 store 共享数据:

var napa = require('napajs');
var zone = napa.zone.create('zone1');
var store = napa.store.create('store1');// Set 'key1' in node.
store.set('key1', {
 a: 1,
 b: "2",
 c: napa.memory.crtAllocator // transportable complex type.}; // Get 'key1' in another thread.zone.execute(() => { var store = global.napa.store.get('store1');
 console.log(store.get('key1'));
});

尽管很方便,但不建议在同一个事务里用 store 传值,因为这样做不仅仅只传输了数据(还附带了别的事情,比如加锁)。另外,虽然有垃圾回收机制,但开发者还是应当在使用完数据后手动删除相应的 key。


安装

执行 npm install napajs 安装。

在 OSX 系统安装后执行会报错,在 gi中里也有同样的提问,解决方法是按照官方的构建文档,自己手动构建。

最新版 v0.1.4 版本已经修复上述问题。

步骤如下:

  1. 安装先决依赖

    (1)Install C++ compilers that support C++14:

    xcode-select --install

(2)Install CMake:

brew install cmake

(3)Install cmake-js:

npm install -g cmake-js

2.通过 npm 构建

npm install --no-fetch


快速上手示例

1.计算圆周率 π 值

下面是一个计算 π 值的例子,演示了如何利用多线程执行子任务。

var napa = require("napajs");

// Change this value to control number of napa workers initialized

const NUMBER_OF_WORKERS = 4;

// Create a napa zone with number_of_workers napa workers

var zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });

// Estimate the value of π by using a Monte Carlo method

function estimatePI(points) {

var i = points;

var inside = 0;

while (i-- > 0) {

var x = Math.random();

var y = Math.random();

if ((x * x) + (y * y) <= 1) {

inside++;

}

}

return inside / points * 4;

}

function run(points, batches) {

var start = Date.now();

var promises = [];

for (var i = 0; i < batches; i++) {

promises[i] = zone.execute(estimatePI, [points / batches]);

}

return Promise.all(promises).then(values => {

var aggregate = 0;

values.forEach(result => aggregate += result.value);

printResult(points, batches, aggregate / batches, Date.now() - start);

});

}

function printResult(points, batches, pi, ms) {

console.log('\t' + points

+ '\t\t' + batches

+ '\t\t' + NUMBER_OF_WORKERS

+ '\t\t' + ms

+ '\t\t' + pi.toPrecision(7)

+ '\t' + Math.abs(pi - Math.PI).toPrecision(7));

}

console.log();

console.log('\t# of points\t# of batches\t# of workers\tlatency in MS\testimated π\tdeviation');

console.log('\t---------------------------------------------------------------------------------------');

// Run with different # of points and batches in sequence

run(4000000, 1)

.then(result => run(4000000, 2))

.then(result => run(4000000, 4))

.then(result => run(4000000, 8))

运行结果如下,当设置为 1 组、2 组、4 组子任务并行计算时,可以看出执行时间有明显提升,当设置为 8 组子任务并行计算时,由于没有更多的空闲 worker 资源,也就没有明显的执行时间的提升。

# of points # of batches # of workers latency in MS estimated π deviation

---------------------------------------------------------------------------------------

40000000 1 4 1015 3.141619 0.00002664641

40000000 2 4 532 3.141348 0.0002450536

40000000 4 4 331 3.141185 0.0004080536

40000000 8 4 326 3.141620 0.00002724641

2.计算斐波那契数列

var napa = require("napajs");

// Change this value to control number of napa workers initialized.

const NUMBER_OF_WORKERS = 4;

// Create a napa zone with number_of_workers napa workers.

var zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });

/*

Fibonacci sequence

n: | 0 1 2 3 4 5 6 7 8 9 10 11 ...

-------------------------------------------------------------------------

NTH Fibonacci: | 0 1 1 2 3 5 8 13 21 34 55 89 ...

*/

function fibonacci(n) {

if (n <= 1) {

return n;

}

var p1 = zone.execute("", "fibonacci", [n - 1]);

var p2 = zone.execute("", "fibonacci", [n - 2]);

// Returning promise to avoid blocking each worker.

return Promise.all([p1, p2]).then(([result1, result2]) => {

return result1.value + result2.value;

});

}

function run(n) {

var start = Date.now();

return zone.execute('', "fibonacci", [n])

.then(result => {

printResult(n, result.value, Date.now() - start);

return result.value;

});

}

function printResult(nth, fibonacci, ms) {

console.log('\t' + nth

+ '\t' + fibonacci

+ '\t\t' + NUMBER_OF_WORKERS

+ '\t\t' + ms);

}

console.log();

console.log('\tNth\tFibonacci\t# of workers\tlatency in MS');

console.log('\t-----------------------------------------------------------');

// Broadcast declaration of 'napa' and 'zone' to napa workers.

zone.broadcast(' \

var napa = require("napajs"); \

var zone = napa.zone.get("zone"); \

');

// Broadcast function declaration of 'fibonacci' to napa workers.

zone.broadcast(fibonacci.toString());

// Run fibonacci evaluation in sequence.

run(10)

.then(result => { run(11)

.then(result => { run(12)

.then(result => { run(13)

.then(result => { run(14)

.then(result => { run(15)

.then(result => { run(16)

}) }) }) }) }) })

运算结果:

Nth Fibonacci # of workers latency in MS

-----------------------------------------------------------

10 55 4 10

11 89 4 13

12 144 4 15

13 233 4 22

14 377 4 31

15 610 4 50

16 987 4 81


路漫漫其修远兮,吾将上下而求索.

相关推荐

无畏契约手游测试资格获取方法,安卓IOS下载教程

《无畏契约:源能行动》是拳头游戏与腾讯光子工作室联合开发的《无畏契约》正版手游,延续了端游的5v5战术射击核心玩法,并针对移动端进行了操作优化。游戏以快节奏的爆破模式为核心,融合角色技能系统、经济策略...

微软正在测试重新设计的Office图标 但您现在可以提前下载重制版本

今年4月,有消息称微软正在征求用户对一组Office图标7年来首次重制版的看法(上一次重制是在2018年末)。现在,有人决定自己动手,制作了一套微软的高分辨率图标包与用户共享以获得反馈。Reddi...

AB Download Manager:一款可以替代IDM的开源桌面下载管理器

软件介绍IDM下载器大家应该多少都知道一点,如果不知道的话只能自行百度了,但是IDM本身是需要付费的,而今天推荐的这款软件,在下载方面是和IDM差不多的,大概有90%的相似度,感兴趣的朋友可以体验一下...

《夺宝奇兵》PS5光盘仅20G:其余需联网下载

来源:游民星空【《夺宝奇兵》PS5光盘仅20G:其余需联网下载】据游戏测试账号“DoesItPlay1”在推特发布动态表示,《夺宝奇兵:古老之圈》PS5实体光盘只存储了20GB的游戏数据,其余内容需要...

薇姐聊诗词7:诗词创作韵部查询及检测工具

薇姐聊诗词7:诗词创作韵部查询及检测工具。·1、诗词创作中所用韵脚哪里找?平水韵:106部,分平声30部、上声29部、去声30部、入声17部,反映中古汉语语音体系。新韵:(中华新韵)14部,以普通话为...

阿里云国际站:怎样模拟高并发测试场景?

本文由【云老大】TG@yunlaoda360撰写一、使用JMeter安装JMeter:从JMeter官网下载并安装JMeter。创建测试计划:打开JMeter,创建一个新的测试计划。添加线程组...

Android Studio 新增 AI 驱动的测试和更智能的崩溃诊断功能

随着GoogleI/O2025大会的落幕,值得注意的是,谷歌在AndroidStudio中引入了几项新功能,旨在改善Android应用程序的开发流程。最新版本集成了更先进的AI工...

如何在本地测试PHP源码的网站

通常,我们测试自建网站或从网上获取的PHP源码时,若直接上传到服务器,出错后再修改会很麻烦,因此一般会选择先在本地电脑上进行测试。1、先下载喜欢的源码,很多网站提供下载,如源码论坛等。这些源码是现成...

显卡性能测试工具3DMark06的应用教程

显卡作为计算机的重要组成部分,也是主要的输出设备。在计算机系统中,图形处理性能的瓶颈往往在于显卡。若要评估显卡性能,用户可以借助专业的检测工具3DMark,判断显卡是否能满足当前需求,或者是否需要...

Downie4 安装教程(轻松获取视频素材)

效果一、准备工作下载软件链接:http://www.macfxb.cn二、开始安装1、双击运行软件,将其从左侧拖入右侧文件夹中,等待安装完毕2、应用程序显示软件图标,表示安装成功三、运行测试1、打开软...

如何使用瑞星杀毒软件的网速测试功能

下面为大家介绍瑞星杀毒软件的网速测试功能。1、打开安全工具,找到网速测试,点击下载后开启。2、打开网速测试页面,点击开始测试按钮。3、测试结束后,你就能知晓自己的网速了。(9744667)...

阿里云国际站:如何测试服务器真实带宽?

本文由【云老大】TG@yunlaoda360撰写基于命令行工具测试iperf/iperf3:服务器端:在服务器上安装iperf后,运行iperf-s或iperf3-s启动服务端,...

CentOS Docker 安装

Docker支持以下的64位CentOS版本:CentOS9(stream)更高版本...必须启用centos-extras仓库,该仓库默认启用,如果您禁用了它,需要重新启用。使用官...

Fast YOLO:用于实时嵌入式目标检测(附论文下载)

关注并星标从此不迷路计算机视觉研究院公众号ID|ComputerVisionGzq计算机视觉研究院专栏作者:Edison_G目标检测被认为是计算机视觉领域中最具挑战性的问题之一,因为它涉及场景中对象分...

aigc检测报告与查重监测报告

哈喽学妹学弟们!最近是不是都在忙着写论文呢?记得当初我写论文的时候,也被AIGC检测报告和查重监测报告搞得晕头转向。不过经过我的一番摸索,终于搞清楚了它们之间的区别和联系。来来来,学姐今天就来给你们传...