性能:Immutable.js Map vs List vs plain JS

8 浏览
0 Comments

性能:Immutable.js Map vs List vs plain JS

我的基准测试有什么问题吗?为什么Immutable.js的find()方法比array.find()方法慢8倍?

好吧,这样说有些不公平,因为我在Immutable.List中使用了Immutable.Map。但对我来说,这是一个真实世界的例子。如果我使用Immutable.js,那是为了保护不可变性并在某些方面获得性能提升(其中结构共享发挥作用)。仅在对象的根部使用Immutable.js是没有意义的。

下面的基准测试实际上来自于另一个问题(也是我的问题)。我对结果感到非常惊讶,所以我必须单独发布它来弄清楚。我在基准测试中做错了什么,还是性能差异确实这么大?

背景:

我的应用程序中的一些数据可以被视为应用程序元数据。原始数据存储在服务器上的数据库中。对元数据的更新不会经常发生。应用程序将在启动时检查更新后的元数据。

我在应用程序的任何地方都使用Immutable.js,但是对于元数据,我将回退到普通的js。对于这种类型的数据,没有必要使用复杂的结构共享。

测试的目的是在集合中按键查找值:

- 包含10个项的集合

- 查找一百万次

- Mac mini core i7 2.6

结果:

- 使用强制转换键的普通JS对象:8毫秒

- 使用find()的普通JS数组:127毫秒

- 使用数字键的Immutable.Map:185毫秒

- 使用find()的Immutable.List:972毫秒!!让我感到困惑

由于我使用React Native,如果想实现60帧每秒,我总是必须注意16毫秒的限制。基准测试的值似乎不是线性的。只进行100次查找的测试使用Map花费1毫秒,而使用List花费2毫秒。这相当昂贵。

测试代码:

let Immutable = require('immutable');

let mapTest = Immutable.Map()

.set(1, Immutable.Map({value: 'one'}))

.set(2, Immutable.Map({value: 'two'}))

.set(3, Immutable.Map({value: 'three'}))

.set(4, Immutable.Map({value: 'four'}))

.set(5, Immutable.Map({value: 'five'}))

.set(6, Immutable.Map({value: 'six'}))

.set(7, Immutable.Map({value: 'seven'}))

.set(8, Immutable.Map({value: 'eight'}))

.set(9, Immutable.Map({value: 'nine'}))

.set(10, Immutable.Map({value: 'ten'}));

let listTest = Immutable.fromJS([

{key: 1, value: 'one'},

{key: 2, value: 'two'},

{key: 3, value: 'three'},

{key: 4, value: 'four'},

{key: 5, value: 'five'},

{key: 6, value: 'six'},

{key: 7, value: 'seven'},

{key: 8, value: 'eight'},

{key: 9, value: 'nine'},

{key: 10, value: 'ten'}

])

let objTest = {

1: {value: 'one'},

2: {value: 'two'},

3: {value: 'three'},

4: {value: 'four'},

5: {value: 'five'},

6: {value: 'six'},

7: {value: 'seven'},

8: {value: 'eight'},

9: {value: 'nine'},

10: {value: 'ten'}

};

let arrayTest = [

{key: 1, value: 'one'},

{key: 2, value: 'two'},

{key: 3, value: 'three'},

{key: 4, value: 'four'},

{key: 5, value: 'five'},

{key: 6, value: 'six'},

{key: 7, value: 'seven'},

{key: 8, value: 'eight'},

{key: 9, value: 'nine'},

{key: 10, value: 'ten'}

];

const runs = 1e6;

let i;

let key;

let hrStart;

console.log(' ')

console.log('mapTest -----------------------------')

key = 1;

hrstart = process.hrtime();

for(i=0; i

let result = mapTest.getIn([key, 'value'] )

key = (key >= 10) ? 1 : key + 1;

}

hrend = process.hrtime(hrstart);

console.info("Execution time (hr): %dms", hrend[0] * 1000 + hrend[1]/1000000);

console.log(' ')

console.log('listTest -----------------------------')

key = 1;

hrstart = process.hrtime();

for(i=0; i

let result = listTest

.find(item => item.get('key') === key)

.get('value');

key = (key >= 10) ? 1 : key + 1;

}

hrend = process.hrtime(hrstart);

console.info("Execution time (hr): %dms", hrend[0] * 1000 + hrend[1]/1000000);

console.log(' ')

console.log('arrayTest -----------------------------')

key = 1;

hrstart = process.hrtime();

for(i=0; i

let result = arrayTest

.find(item => item.key === key)

.value

key = (key >= 10) ? 1 : key + 1;

}

hrend = process.hrtime(hrstart);

console.info("Execution time (hr): %dms", hrend[0] * 1000 + hrend[1]/1000000);

console.log(' ')

console.log('objTest -----------------------------')

key = 1;

hrstart = process.hrtime();

for(i=0; i

let result = objTest[key].value

key = (key >= 10) ? 1 : key + 1;

}

hrend = process.hrtime(hrstart);

console.info("Execution time (hr): %dms", hrend[0] * 1000 + hrend[1]/1000000);

0