LRU缓存问题的两种解决方案:为什么一个比另一个快?

时间:2019-03-14 20:44:25

标签: c# performance

我提交了一个解决方案来解决leetcode的LRU缓存问题,在运行时方面它的排名为33%。然后,我看到提交速度比其余提交速度快98%,与我的提交几乎完全相同,只是存在细微差异。我注意到的最大区别是,它们使用了用户定义的结构,而不是使用整数的字典和链表。我不明白为什么这会影响性能。谢谢!

我的解决方案:

PersoUtils.getHearthBeat(1)
// Hearthbeat 1
.progress(function(msg) {
    console.log(msg);
})
.fail(function(id, err) {
    console.log('ERROR while getting beat' + id + ' : ' + err);
})
.then(function(id, beat) {
    console.log('got beat ' + id + ': ' + JSON.stringify(beat));
    return PersoUtils.getHearthBeat(2); // new value, say depending on 'beat'
})
 // Hearthbeat 2
.progress(function(msg) {
    console.log(msg);
})
.fail(function(id, err) {
    console.log('ERROR while getting beat' + id + ' : ' + err);
})
.then(function(id, beat) {
    console.log('got beat ' + id + ': ' + JSON.stringify(beat));
    return PersoUtils.getHearthBeat(3); // new value, say depending on 'beat'
})
 // Hearthbeat 3
.progress(function(msg) {
    console.log(msg);
})
.fail(function(id, err) {
    console.log('ERROR while getting beat' + id + ' : ' + err);
})
.done(function(id, beat) {
    console.log('got beat ' + id + ': ' + JSON.stringify(beat));
});

更快的解决方案:

public class LRUCache 
{
    Dictionary<int,int> LRUDict = new Dictionary<int,int>();
    LinkedList<int> keys = new LinkedList<int>();
    int capacity = 0;
    public LRUCache(int capacity) {
        this.capacity = capacity;
    }

    public int Get(int key) {
        int retval = -1;
        int entry;
        if (LRUDict.TryGetValue(key,out entry))
        {
            retval = entry;
            keys.Remove(key);
            keys.AddLast(key);
        }
        return retval;
    }

    public void Put(int key, int value) {
        //case 1: exists, no need to increment count and check capacity, just change value and move up
        if (LRUDict.ContainsKey(key))
        {
            keys.Remove(key);
            keys.AddLast(key);
        }
        //case 2: does not exist, need to add new entry, may need to kick out oldest one
        else
        {
            keys.AddLast(key);
            if (keys.Count > capacity)
            {
                int LRUKey = keys.First.Value;
                keys.RemoveFirst();
                LRUDict.Remove(LRUKey);
            }
        }
        LRUDict[key] =value;
    }
}

1 个答案:

答案 0 :(得分:2)

第二种解决方案更快,因为它删除了LinkedListNode,可以在O(1)中完成。第一种解决方案是删除一个值,该值需要搜索链接列表或O(n)时间。

因此,第一个解决方案的伸缩性将非常差,并增加了更多项目。

查看两种情况下使用的确切的Remove方法重载-以及相应的文档。