【问题标题】:RxJS performance numbers at animation speeds动画速度下的 RxJS 性能数据
【发布时间】:2017-08-18 06:38:56
【问题描述】:
当事件以类似动画的速度(例如每秒至少 20 次)发生时,任何人都知道RxJS 的性能吗?我正在寻找将 javascript 模拟器(每秒至少执行 20 次模拟步骤)重构为使用事件和侦听器,我想知道使用 RxJS 作为事件队列/侦听器解决方案是否可行(所以我不不必自己写)。
我也很好奇当你有多达一百个东西在一个 observable 上监听时它是如何扩展的,以便让我了解如何构建视图更新(我是否应该只保留几个监听器并保留一张地图需要更新或保持简单的视图元素集,只需让每个元素注册一个侦听器即可)。
Google 搜索得到了这个:
Is RxJS faster than imperative?
结果有点令人担忧(比普通代码慢 10 倍,但对于具有 1 个侦听器的系统,每个事件仍然只需要额外的 0.005 毫秒)。我也会进行自己的实验,但是任何可扩展性信息(不仅是性能,还有其他诸如簿记和垃圾收集等)来自在具有大量侦听器的真实项目中使用 RxJS 的人都会非常有用。
【问题讨论】:
标签:
javascript
performance
rxjs
【解决方案1】:
我在 RxJS 5 上进行了一些初步实验,结果如下:
- 设置:10000 长度的事件数组
- 订阅人数:1 到 20
- 输出格式:Rx_{n}x_observer:处理 n 个订阅者的订阅调用的总时间。
基准代码:
var eventQueue: number[];
var initEventQueue = function () {
const INIT_MAX = 10000;
eventQueue = new Array<number>(INIT_MAX);
for (let i = 0; i < INIT_MAX; i++) {
eventQueue[i] = i;
}
}
export var testObservables = function () {
let observable = Rx.Observable;
initEventQueue();
for (let OBSERVERS = 1; OBSERVERS <=20; OBSERVERS++) {
let timerName = `Rx_${OBSERVERS}x_observer`;
console.time(timerName);
let eventQueueObservable = observable.from(eventQueue)
.map(function (x: number) { return x; });
for (let ctr = 0; ctr < OBSERVERS; ctr++) {
eventQueueObservable
.subscribe(function (x: number) {
let y= x * ctr;
return y;
});
}
console.timeEnd(timerName);
}
}
输出:
Rx_1x_observer: 7.261962890625ms
Rx_2x_observer: 9.14794921875ms
Rx_3x_observer: 2.1669921875ms
Rx_4x_observer: 1.617919921875ms
Rx_5x_observer: 1.93310546875ms
Rx_6x_observer: 3.100830078125ms
Rx_7x_observer: 3.074951171875ms
Rx_8x_observer: 2.90673828125ms
Rx_9x_observer: 5.216796875ms
Rx_10x_observer: 4.488037109375ms
Rx_11x_observer: 5.946044921875ms
Rx_12x_observer: 4.888916015625ms
Rx_13x_observer: 5.302978515625ms
Rx_14x_observer: 5.02197265625ms
Rx_15x_observer: 7.6201171875ms
Rx_16x_observer: 7.156005859375ms
Rx_17x_observer: 6.6640625ms
Rx_18x_observer: 8.875ms
Rx_19x_observer: 9.205078125ms
Rx_20x_observer: 9.756103515625ms
前几个结果中的高数字很可能是 JIT 优化尚未启动的结果,后面的结果更有可能表明实际性能。如果数字正确,则每个事件*订阅者的开销远低于 0.01 毫秒,这对于动画时间更新来说绰绰有余(至少只要您保持订阅者代码简单)。
不幸的是,我还发现订阅者必须明确取消订阅以避免垃圾收集问题,这不适用于我的目标架构。我可能会改用使用弱映射的标准侦听器模式。