javascript - 默认 Javascript 对象很大时速度很慢?

标签 javascript node.js

我正在做一个收集单词共现的修改版本,所以我编写了自己的 javascript,我正在跟踪三个对象中的出现。但是,一旦对象变大(约 800 万、300 万和 172000),每 100000 个句子需要 5 秒的函数现在需要几分钟来完成一个包含 30 个单词(30 个标记)的句子。我离我的 RAM 上限还很远(我还有 12 GB 的 RAM 可以使用,而程序只使用了 2.2GB)。使用 Node.js v17.3.1。

为什么当对象变大时我的函数需要这么长时间(即使句子保持相同的长度)?除了 Javascript 的默认对象之外,我是否应该使用其他对象,或者当这些对象如此之大时,有没有办法提高访问和设置这些对象的速度?

代码:

  let posCounts = {};
  let negCounts = {};
  // the number of times each word occurs
  let wordCounts = {};
  let tokens = // some function that gets tokens;
    for (let k = 0; k < tokens.length; k++) {
      // count word occurences
      if (tokens[k] in wordCounts) {
        wordCounts[tokens[k]] += 1;
      } else {
        wordCounts[tokens[k]] = 1;
      }
      for(let tok = k + 1; tok < tokens.length; tok++) {
        if (tok == k) {
          // avoid word to self cooccurrence
          // should no longer be possible
          continue;
        } else {
           // check which form of the cooccurence exists already in either count
           actual_tok = (tokens[k] + "-" + tokens[tok]);
           if(actual_tok in posCounts || actual_tok in negCounts) {
             // no-op
           } else {
             actual_tok = (tokens[tok] + "-" + tokens[k]);
           }

           // condition set before this block of code
           if(condition) {
             if (actual_tok in posCounts) {
               posCounts[actual_tok] += 1;
             } else {
               posCounts[actual_tok] = 1;
             }
           } else {
             if (actual_tok in negCounts) {
               negCounts[actual_tok] += 1;
             } else {
               negCounts[actual_tok] = 1;
             }
           }
         }
      }


    }

更新:我尝试通过 node train_matrices.js --max-old-space-size=12288node train_matrices.js --max_old_space_size=12288< 增加堆大小(下划线而不是破折号),这也不起作用。

最佳答案

可能不是您代码中的主要问题,但您可以通过更改此结构来减少查找次数:

  if (tokens[k] in wordCounts) {
    wordCounts[tokens[k]] += 1;
  } else {
    wordCounts[tokens[k]] = 1;
  }

为此:

  let token = tokens[k];
  let cnt = wordCounts[token] || 0;
  wordCounts[token] = cnt + 1;

而且,正如我在评论中所说,我读过一个带有 .get().set()Map 对象> 当有很多动态创建的键时更适合,而普通对象更适合当你有很多具有相同键的对象时(因为 JS 编译器有时可以为它创建类似 C 的结构),但这不能'当您定期添加新 key 时,就不需要这样做了。

关于javascript - 默认 Javascript 对象很大时速度很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71044915/

相关文章:

javascript - bool 柯里化(Currying) Javascript

node.js - 在 Expressjs 中获取 TypeError : path must be absolute or specify root to res. sendFile

javascript - HTML - 使用媒体查询加载单独的布局

javascript - 正则表达式 javascript 仅返回一个值而不是完全匹配

javascript - 通过带有虚线参数的 JavaScript 添加表格标签

node.js - 处理 Mongoose 验证错误——在哪里以及如何处理?

javascript - 使用 atob 解码 base64 字符串会引发错误,即使它不包含任何非 ASCII 字符

javascript - 2D 游戏中的 keyPressed 倒置 [P5.js]

javascript - 添加样式表但不添加样式

node.js - 如何修复 : "EPROTO" Error after upgrading Node's version