JavaScript 中数组与对象的效率

2024-02-16

我有一个可能包含数千个对象的模型。我想知道存储它们并在获得单个对象的 id 后检索该对象的最有效方法是什么。 id 是长数字。

这是我正在考虑的两个选择。在选项一中,它是一个带有递增索引的简单数组。在选项 2 中,它是一个关联数组,也可能是一个对象,如果它有所作为的话。我的问题是,当我主要需要检索单个对象,但有时还需要循环遍历它们并进行排序时,哪一个更有效。

使用非关联数组的选项一:

var a = [{id: 29938, name: 'name1'},
         {id: 32994, name: 'name1'}];
function getObject(id) {
    for (var i=0; i < a.length; i++) {
        if (a[i].id == id) 
            return a[i];
    }
}

使用关联数组的选项二:

var a = [];  // maybe {} makes a difference?
a[29938] = {id: 29938, name: 'name1'};
a[32994] = {id: 32994, name: 'name1'};
function getObject(id) {
    return a[id];
}

Update:

好的,我知道在第二个选项中使用数组是不可能的。所以第二个选项的声明行实际上应该是:var a = {};唯一的问题是:在检索具有给定 id 的对象时,什么性能更好:数组还是以 id 为键的对象。

另外,如果我必须多次对列表进行排序,答案会改变吗?


简而言之:数组通常比对象更快。但没有100%正确的解决方案。

2017 年更新 - 测试和结果

var a1 = [{id: 29938, name: 'name1'}, {id: 32994, name: 'name1'}];

var a2 = [];
a2[29938] = {id: 29938, name: 'name1'};
a2[32994] = {id: 32994, name: 'name1'};

var o = {};
o['29938'] = {id: 29938, name: 'name1'};
o['32994'] = {id: 32994, name: 'name1'};

for (var f = 0; f < 2000; f++) {
    var newNo = Math.floor(Math.random()*60000+10000);
    if (!o[newNo.toString()]) o[newNo.toString()] = {id: newNo, name: 'test'};
    if (!a2[newNo]) a2[newNo] = {id: newNo, name: 'test' };
    a1.push({id: newNo, name: 'test'});
}

原帖 - 解释

你的问题中存在一些误解。

JavaScript 中没有关联数组。仅数组和对象。

这些是数组:

var a1 = [1, 2, 3];
var a2 = ["a", "b", "c"];
var a3 = [];
a3[0] = "a";
a3[1] = "b";
a3[2] = "c";

这也是一个数组:

var a3 = [];
a3[29938] = "a";
a3[32994] = "b";

它基本上是一个有洞的数组,因为每个数组都有连续索引。它比无孔阵列慢。但手动迭代数组甚至更慢(大部分)。

这是一个对象:

var a3 = {};
a3[29938] = "a";
a3[32994] = "b";

这是三种可能性的性能测试:

查找数组 vs 空洞数组 vs 对象性能测试 http://jsben.ch/Y9jDP

Smashing 杂志上有关这些主题的精彩读物:编写快速内存高效的 JavaScript http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/

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

JavaScript 中数组与对象的效率 的相关文章

随机推荐

  • Xamarin iOS 构建的 DevOps CI 错误 在钥匙串中找不到有效的 iOS 代码签名密钥

    我已经为我的 Xamarin iOS 应用程序创建了 YAML 构建配置 并提供了证书文件 p12 和 mobileprovision 但是当管道运行时 它在应用程序的构建步骤中失败 证书安装通过 Note具有相同证书文件和密码的构建在应用
  • Keras 中的回调异常 - Tensorflow 2.0 - Python

    以下代码在与 Keras 打包的 MNIST 数据上运行顺序 Keras 模型 非常简单 在运行以下代码时 我遇到异常 该代码很容易重现 import tensorflow as tf class myCallback tf keras c
  • 有没有办法获取 Visual Studio 使用的构建命令行?

    我想从命令行进行构建 但我想从 Visual Studio 2012 获取确切的命令行语法 这样我就不必手动找出所有标志 导入和其他参数 有没有办法让 Visual Studio 显示这些信息 在 Visual Studio 中生成项目或解
  • 使用 Service Worker 处理离线时的文件上传

    我们有一个 Web 应用程序 使用 AngularJS 构建 我们也逐渐添加 PWA 功能 服务工作线程 可启动项 通知等 我们的网络应用程序的功能之一是能够在离线状态下完成网络表单 目前 我们在离线时将数据存储在 IndexedDB 中
  • Mongoid embeds_many:推送文档而不保存以保留脏状态

    在 Mongoid 中 将文档推送到embeds many关系自动将文档保存到数据库中 通常 这很好 但是当我需要跟踪嵌入文档的更改时 我会遇到问题 假设您有两个模型 class List include Mongoid Document
  • 从函数 React Native 获取字符串结果

    我创建了一个连接到 redux 并返回当前加载的组件item sname 作为导航标题 但是当我尝试从此组件获取标题时 它会出现以下错误 Error title cannot be defined as a function in navi
  • 不支持的major.minor版本51.0(无法加载类org.postgresql.Driver)

    使用maven创建一个Web应用程序并将其部署在heroku上 一切正常 但当我调用使用 postgresql 9 2 1002 jdbc4 驱动程序的操作时 我得到 java lang UnsupportedClassVersionErr
  • Android Studio 3.5 原因:buildOutput.apkData 不得为 null Clean & Rebuild 已尝试

    在我将 Android Studio 3 4 更新到 3 5 并想要构建签名 APK 后 我收到错误 原因 buildOutput apkData 不能为 null 错误 我已经尝试过清理和制作项目以及清理和重建项目 但没有成功 我正在使用
  • 从 iOS 15.0 同步 CloudKit 后,CoreData 中的关系为零

    我正在为一个新应用程序开发 PoC 但我遇到了两个 CoreData 实体的问题InboxItem and CardSet 它们中的每一个都具有可选的 对一 关系 当我在模拟器中启动应用程序并创建这些实体时 模拟器数据库和 CloudKit
  • 如何将对象标记为由 GC(垃圾收集器)进行垃圾收集?

    在Java中 有没有办法markGC 下一次垃圾收集的对象clean up cycle 我听说设置一个对象null不再有效 不 你不能 如果另一个变量引用了它 您会期望发生什么 请注意 您无法设置object为 null 您只能设置一个va
  • 如何将 JsonConverter 与 JToken.ToObject<>() 方法一起使用?

    我正在将一个大型 JSON 文件成功读取到 JObjects 中 我要反序列化的类型之一具有 System Drawing Color 类型的属性 此属性的 JSON 具有表示颜色的整数值 当我尝试执行 ToObject 时 我得到 将值
  • 查找插入特定表的存储过程

    有没有办法找到存储过程在表中创建的条目 举例来说 存储过程A插入表A存储过程 B 插入表 A存储过程 C 插入表 B 我希望查询返回存储过程 A 和存储过程 B 的名称 我现在已经得到了这个 但它所做的只是找到存储过程 我认为这将是查找存储
  • 暂时禁用mysql远程访问

    我需要在 Linux 服务器上的每晚 mysql 维护期间禁用远程访问 以便在此期间没有人可以查询数据库 我无法执行 SERVICE MYSQL STOP 因为那样我就无法执行我需要执行的操作 截断并重建几个表 有没有办法暂时关闭外部访问
  • 如何避免 R Fisher.test 工作区错误

    我正在对大量列联表进行渔夫精确检验 并保存生物信息学问题的 p val 其中一些列联表很大 因此我尽可能地增加了工作空间 但是当我运行以下代码时出现错误 result lt fisher test data workspace 2e9 LD
  • 命令行流网络摄像头,带有来自 Ubuntu 服务器的 WebM 格式的音频

    我正在尝试从连接到无头 Ubuntu 服务器 运行 Maverick 10 10 的网络摄像头传输视频和音频 我希望能够以 WebM 格式 VP8 视频 OGG 进行流式传输 带宽有限 因此流必须低于 1Mbps 我尝试过使用 FFmpeg
  • 获取用户使用discord.py发送的最后一条消息?

    我想知道是否有办法让机器人使用 Python 中的discord py 获取用户在服务器聊天中发送的最后一条消息 多谢 旧答案discord py async 重写前 Use log froms http discordpy readthe
  • Scala 关闭挂钩从未运行?

    scaladoc 为sys addShutdownHook says shutdown hooks are NOT guaranteed to be run 现在这是完全合理的 因为如果您向 JVM 发送 SIGKILL 或任何 Windo
  • 整数数组的ArrayList

    我正在尝试编写一个简单的游戏 其中敌人在网格上追逐玩家 我正在使用维基百科寻路页面上的简单寻路算法 这涉及创建两个列表 每个列表项包含 3 个整数 这是我尝试构建和显示这样一个列表的测试代码 当我运行以下代码时 它会为 ArrayList
  • R中随机选择一个样本

    我必须找到一种方法从集合 S 中随机选择 R 中的一个样本 集合 S 由 I1 集合中的样本组成 I1 lt c 1 2 3 4 5 6 s1 lt c 1 2 1 s2 lt c 1 5 6 s3 lt c 2 1 1 s4 lt c 5
  • JavaScript 中数组与对象的效率

    我有一个可能包含数千个对象的模型 我想知道存储它们并在获得单个对象的 id 后检索该对象的最有效方法是什么 id 是长数字 这是我正在考虑的两个选择 在选项一中 它是一个带有递增索引的简单数组 在选项 2 中 它是一个关联数组 也可能是一个