在Chrome 36上使用Javascript循环遍历此数组的最快方法

时间:2014-07-26 10:30:37

标签: javascript arrays loops

我有一个非常大的数组,看起来与此类似

var counts = ["gfdg 34243","jhfj 543554",....] //55268 elements long

这是我目前的循环

var replace = "";
var scored = 0;
var qgram = "";
var score1 = 0;
var len = counts.length;

function score(pplaintext1) {
    qgram = pplaintext1;
    for (var x = 0; x < qgram.length; x++) {
        for (var a = 0, len = counts.length; a < len; a++) {
            if (qgram.substring(x, x + 4) === counts[a].substring(0, 4)) {
                replace = parseInt(counts[a].replace(/[^1-9]/g, ""));
                scored += Math.log(replace / len) * Math.LOG10E;
            } else {
                scored += Math.log(1 / len) * Math.LOG10E;
            }
        }
    }
    score1 = scored;
    scored = 0;
} //need to call the function 1000 times roughly

我必须多次遍历此数组,并且我的代码运行缓慢。我的问题是循环这个数组的最快方法是什么,所以我可以节省尽可能多的时间。

1 个答案:

答案 0 :(得分:3)

您的counts数组似乎是与其关联的唯一字符串和值的列表。改为使用对象,键入唯一的字符串,例如:

var counts = { gfdg: 34243, jhfj: 543554, ... };

这将大规模通过将O(n)内部循环替换为O(1)对象密钥查找来消除对log(1 / n) = -log(n)内部循环的需求,从而提高性能。

此外,避免分裂 - log(1/len) * Math.LOG10E - 并在循环外移动循环不变量。您的if实际上是每次传递中添加的常量,但在第一个Math.log(replace)分支中您还需要考虑var len = Object.keys(counts).length; function score(text) { var result = 0; var factor = -Math.log(len) * Math.LOG10E; for (var x = 0, n = text.length - 4; x < n; ++x) { var qgram = text.substring(x, x + 4); var replace = counts[qgram]; if (replace) { result += Math.log(replace) + factor; } else { result += len * factor; // once for each ngram } } return result; } ,这在日志数学中意味着添加它。

P.S。避免使用外部范围的状态变量来获得分数!我认为以下正确复制了您的评分算法:

{{1}}