带数字键的 Immutable.js 映射(包括性能测试)

2024-05-28

我在 React Native 应用程序中将 Immutable.js 与 Redux 结合使用。

元数据(例如查找表)是从服务器获取的,并作为 Immutable.Map 保存在应用程序本地。查找值的键是整数(数据库中的主键)。

当我获取数据时,所有整数键都被强制转换为字符串。这是 js 对象的正常行为。因此,当创建查找映射时,键将是字符串。

Example:

let colors = Immutable.Map({
  '10': 'yellow',
  '20': 'pink',
  ..
})

引用查找值的对象将引用存储为数字,如下所示:

let michael = Immutable.Map({
  name: 'Michael',
  colorId: 10
})

由于 Immutable.js 不会将数字键强制转换为字符串,因此我无法执行此操作:

let color = colors.get(michael.get('colorId'))

上面的内容等同于:

let color = colors.get(10)

这是行不通的,因为 id 是一个字符串。这会起作用:

let color = colors.get('10')

我通常使用 Immutable.List 来存储从服务器获取的数据集。为了获取一个项目,我使用 find()。但是小型查找表(本质上是应用程序元数据)的访问非常频繁,并且需要快速。

你如何解决这个问题?以下是一些可供考虑的替代方案:

1.搜索时手动将key转换为字符串

let color = colors.get(michael.get('colorId') + '') 

cons:

  • 这不是一个有吸引力的解决方案。对我来说似乎是错误修剪。

2.使用普通的js对象来查找列表

pros:

  • js 中对象键查找速度很快
  • 自动将键强制转换为字符串,双向(写入和读取)

cons:

  • 理想情况下,我想在任何地方都使用 Immutable.js。

3.使用List.find()查找表

pros:

  • 与大数据集相同的概念

cons:

  • 我不知道使用 List.find() 而不是 Map.get() 对性能的影响

4. 精心设计 Immutable.Map 以使用数字键

let colors = new Immutable.Map()
  .set(10, 'yellow')
  .set(20, 'pink')

pros:

  • 映射中的键将与引用该键的值匹配(即两者都是数字)

cons:

  • 麻烦的
  • 键已经被强制转换为通过线路发送的 json 对象中的字符串,因此我本质上是将它们转换回数字(我认为)

编辑..做了一些性能测试

来自简单性能测试的有趣数据。

  • 10 项的查找列表
  • 求一个值一百万次
  • Mac 迷你酷睿 i7 2.6

带有数字键的 Immutable.Map:185 ms

使用 find() 的 Immutable.List:972 ms

带有强制键的普通 JS 对象:8 ms

使用 find() 的普通 JS 数组:127 ms

由于我使用的是 React Native,如果我想达到 60 fps,我总是必须注意 16 毫秒的限制。基准值似乎不是线性的。仅使用 100 次查找来运行测试,使用 Map 需要 1 毫秒,使用列表需要 2 毫秒。那是相当昂贵的。

我在基准测试中做错了什么吗?否则我想我现在必须把 Immutable.js 排除在外:(

测试代码

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<runs; 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<runs; 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<runs; 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<runs; 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);

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带数字键的 Immutable.js 映射(包括性能测试) 的相关文章

随机推荐

  • SSIS Master 包执行来自另一个项目的包

    我有多个SSIS项目 但其中的一些包是相同的 我想创建一个包含所有内容的项目generic包并将其他项目与他们的特定包一起保存 所以我的问题是 是否有可能有一个主包可以执行并将父变量传递给另一个项目的包 我是 SSIS 新手 如果这是一个明
  • 电子节点集成不起作用,也普遍奇怪的电子行为[重复]

    这个问题在这里已经有答案了 我是 Electron 的新手 我一直在努力让它工作 我遇到了无法解释的行为 所以这里有一个总结 我无法让 Electron 和 html 之间的通信正常工作 即使我有nodeIntegration true 网
  • 在 cl-mongo 中实现 MongoDB SASL 身份验证

    我已经从 fons 分叉了 cl mongo common lisp MongoDB 库 存储库 因为它已经不再维护并且不支持 SCRAM SHA 1 登录过程 这是我的叉子 https github com mprelude cl mon
  • 合并具有公共字段的列表的最快方法?

    我正在学习 F 并且正在做赔率比较服务 ala www bestbetting com 以将理论付诸实践 到目前为止 我有以下数据结构 type price Bookie string Odds float32 type selection
  • 如何缩放曼德尔布罗集

    我已经成功实现了维基百科文章中所述的曼德尔布罗集 但我不知道如何放大特定部分 这是我正在使用的代码 void createSetWithWidth int width Height int height Thing void int int
  • 为什么/何时应该使用泛型方法?

    学习Java的时候遇到过通用方法 public
  • 将连续行与相同的列值合并

    我有一个看起来像这样的东西 我该如何处理 0 d 0 The DT 1 Skoll ORGANIZATION 2 Foundation ORGANIZATION 3 4 based VBN 5 in IN 6 Silicon LOCATIO
  • 检测笔记本电脑盖子的关闭和打开

    是否可以检测笔记本电脑的盖子何时打开或关闭 从我读到的内容来看 这是不可能的 但 SO 之前已经帮助我完成了不可能的任务 我发现唯一可能朝着正确方向的事情是关于报告电源按钮所需的 IOCTL 的 MSDN 博客文章 https learn
  • 如何在 XAML 中使用其他项目的图像?

    我正在构建一个包含多个项目的解决方案 Windows Phone 应用程序 其中一个项目是用于 品牌 的 它包含一些特定的代码和图像 其想法是该项目可以更换为不同的品牌 我的应用程序页面位于主项目中 我想在主应用程序的 UI 中显示存储在第
  • Spring MVC:通用 DAO 和服务类

    我正在 Spring MVC 中编写网页 我使用 Generic DAO 编写了所有 DAO 现在我想重写我的服务类 我该如何写 通用服务 我的 DAO 如下 DAO package net example com dao import j
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • 将 SAS 中的三次样条有效地拟合到特定的对象网格

    我有一个数据集mydat具有以下变量 MNES IV 0 84 0 40 0 89 0 34 0 91 0 31 0 93 0 29 0 95 0 26 0 98 0 23 0 99 0 22 1 00 0 22 1 02 0 20 1 0
  • 如何将 Kotlin 的 MutableList 初始化为空 MutableList?

    看起来很简单 但是 我如何初始化 Kotlin 的MutableList清空MutableList 我可以用这种方式破解它 但我确信有更简单的方法 var pusta List
  • 如何使用 Alter Table 在 Access 中创建小数字段?

    我想以编程方式在 MS Access 表中创建一个新列 我尝试过很多排列ALTER TABLE MyTable Add MyField DECIMAL 9 4 NULL 并得到 字段定义中的语法错误 我可以轻松创建一个数字字段Double类
  • 如何在 ASP.NET Core 项目中使用 MStest 测试 Ok() 结果

    我正在使用 MStest 来测试我的控制器 我想测试这个动作 HttpGet Name GetGroups public async Task
  • Rails 6 - 操作文本和 API

    我正在创建一个 Rails 6 0 0 应用程序 它具有以下模块 网络 表格 Cruds Api 我使用的地方有一个 CRUD动作文本 https edgeguides rubyonrails org action text overvie
  • ebean 映射到 BYTEA 的数据类型是什么?

    我有一个游戏 2 0 2 需要在数据库中存储一些文件的应用程序 我们使用 Ebean 作为 ORM 我相信我的数据库中需要一个 BYTEA 列来存储该文件 但我不确定在我的模型中使用什么数据类型 我应该使用某种Blob 或者只是一个byte
  • 随机排列每行的列值

    我正在使用 C NET 开发多项选择题考试生成器 每次做出报告时 都会在数据库中随机挑选问题 并随机调整选项 我可以做随机问题部分 但我不能做选择的洗牌 我有一张表 其中一行如下 question answer distractor1 di
  • 如何在 Jenkinsfile 中将 Artifactory DiscardOldBuilds 设置为 true?

    我正在努力使用 Jenkins 多分支管道来实现构建作业 最后阶段是将构建输出上传到 Artifactory 通过界面配置独立作业时 有一个选项 丢弃来自 Artifactory 的旧构建 这允许我仅保留 要保留的最大构建数 设置中指定的相
  • 带数字键的 Immutable.js 映射(包括性能测试)

    我在 React Native 应用程序中将 Immutable js 与 Redux 结合使用 元数据 例如查找表 是从服务器获取的 并作为 Immutable Map 保存在应用程序本地 查找值的键是整数 数据库中的主键 当我获取数据时