【问题标题】:How to increase performance with dictionary?如何使用字典提高性能?
【发布时间】:2019-09-02 14:01:10
【问题描述】:

我的问题是,我在这段代码中没有最快的性能。 我有 30 个测试,我必须用这段代码解决,但我只解决了 28 个,直到它抛出错误,因为它需要很长时间。

这是我的示例输入:

queryType: ["insert", "insert", "addToValue", "addToKey", "get"]
query: [[1,2], [2,3], [2], [1], [3]]
If queryType[i] === "insert" -> Add at query[i][0] value query[i][1].
If queryType[i] === "addToValue" -> Add query[i][0] to every value.
If queryType[i] === "addToKey" -> Add offset.
If queryType[i] === "get" -> Add query[i][0] to result value.

这是我当前的代码:

function testHashMap(queryType, query) {
    let hash = {};
    let result = 0;
    let offset = 0;
    let len = queryType.length;
    for (let i = 0; i < len; ++i) {
        let querys = query[i][0];
        switch (queryType[i]) {
            case "insert": 
                hash[querys] = query[i][1];
                break;
            case "addToValue": 
                for (let key in hash) {
                    hash[key] += querys;
                }
                break;
            case "addToKey": 
                offset += querys;
                break;
            case "get": 
                result += hash[querys - offset];
                break;
        }
    }
    return result;
}

有人知道如何提高此功能的速度吗? 感谢您的宝贵时间!

【问题讨论】:

  • addToValue 耗时过长。这个练习的重点是弄清楚如何在不实际添加每个值的情况下产生相同的效果。

标签: javascript algorithm performance dictionary


【解决方案1】:

正如 Matt Timmermans 在 cmets 中指出的那样,加快速度的一种方法可能不是实际增加每个值。假设我们的起始值是

[1, 1, 1, 1]

现在为每个元素添加 3,我们记录一个通用的offset, 3。

假设我们现在得到一个插入,[2, 4]。我们想将第三个元素设置为 4,所以我们首先减去我们的偏移量。 4 - 3 = 1 所以我们实际上根本不改变第三个元素!

现在我们被请求get 索引 2 处的元素。我们添加我们的一般偏移量:

1 + 3 = 4

正如预期的那样。

这样,所有更新都保持在O(1) 的时间复杂度,这应该会运行得更快。

【讨论】:

  • queryType: ["insert", "insert", "addToKey", "addToKey", "addToKey", "insert", "addToValue", "addToKey", "addToKey", "get"] query: [[-5,-2], [2,4], [-1], [-3], [1], [3,-2], [-4], [-2], [2], [-8]]现在我们有两次get,现在怎么样了?
  • @RoyBlunk 不确定我是否关注。我在您的示例中看到了一个get,但您说我们有两次get。请提供具有预期输出的完整示例,我将使用我提出的方法进行检查。
  • 我想我忘了这个。例如,您有 ["insert", "get", "insert", "get"],现在您有两次必须将值添加到结果中。但是如果你像你告诉我的那样使用偏移量,没有简单的方法来获取写入值,或者不是吗?
  • @RoyBlunk 是这样的吗?从索引 2 处的元素为 4 开始,我们有 [1, 1, 1, 1], offset: 3。现在第二个插入,[2, -6],所以我们将它设置为(-6) - offset = -9。该列表现在是[1, 1, -9, 1。现在我们再次得到 2,我们得到 -9 + 3 = -6,正如预期的那样。
  • 也许我找错路了,我试试你的方法。
【解决方案2】:

如果这是代码中的热点,则调度对象可能会更快(您的问题似乎就是这种情况):

function testHashMap(queryType, query) {
    let hash = {};
    let result = 0;
    let offset = 0;
    let len = queryType.length;
    const dispatch = {
        insert(i) {
            hash[querys] = query[i][1];
        },
        addToValue() {
            for (let key in hash) {
                hash[key] += querys;
            }
        },
        addToKey() {
            offset += querys;
        },
        get() {
            result += hash[querys - offset];
        }
    };
    for (let i = 0; i < len; ++i) {
        let querys = query[i][0];
        (dispatch[queryType[i]] || () => {})(i);
    }
    return result;
}

这是因为 JavaScript 引擎经过调整,可以积极优化热点中的对象方法/属性查找。

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 2013-04-21
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    相关资源
    最近更新 更多