【发布时间】:2022-02-13 15:43:03
【问题描述】:
我正在做一个收集词共现的修改版本,所以我编写了自己的 javascript,我正在跟踪三个对象中的出现。然而,一旦对象变大(约 800 万、300 万和 172000 个),一个每 100000 个句子需要 5 秒的函数现在需要几分钟才能完成一个包含 30 个单词(30 个标记)的句子。我离我的 RAM 上限还差得很远(我还有 12 GB 的 RAM 可以使用,而程序只使用 2.2 GB)。使用 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=12288 和 node train_matrices.js --max_old_space_size=12288(下划线而不是破折号)增加堆大小,但这也不起作用。
【问题讨论】:
-
and the program is only using 2.2GB).您正在接近默认的最大堆大小,因此您可能会遇到很多 GC 命中。您可以尝试使用节点标志--max_old_space_size=4096启动您的节点程序,这将扩展 RAM 节点愿意使用的范围。他们不建议超过 2GB(即使我的一些生产服务器有后台节点进程使用 >= 6GB 有时没有太大问题) -
也许
Map对象会更合适。我读过它比普通对象更好地处理动态插入的键。
标签: javascript node.js